3
回答
关于Android下AES加密、解密的问题,求高手指点迷津,在线解密不出来的问题
本人的AES工具类代码如下,按照项目要求是:AES  ECB模式密钥长度128bit 不偏移 无补码 加密结果编码方式为十六进制,
但是加密出来的密文在线解密:http://www.seacha.com/tools/aes.html    总是解密不出,求指点哪里出问题了
public class AESCipher {
	
    /** 算法/模式/填充
     * AES/ECB/PKCS5Padding **/
    private static final String CipherMode = "AES/ECB/PKCS5Padding";
    /**密钥长度**/
    private static final int KeyLength = 128;//256 bits or 128 bits,192bits
	/**
	 * 
	 * TODO(加密)
	 * @Title: encrypt
	 * @return String
	 * @Exception
	 */
	public static String encrypt(String key, String src) throws Exception {   
        byte[] rawKey = getRawKey(key.getBytes());   
        byte[] result = encrypt(rawKey, src.getBytes());   
        return byte2hex(result);   
    }   
    /**
     *    
     * TODO(解密)
     * @Title: decrypt
     * @return String
     * @Exception
     */
    public static String decrypt(String key, String encrypted) throws Exception {   
        byte[] rawKey = getRawKey(key.getBytes());   
        byte[] enc = hex2byte(encrypted);   
        byte[] result = decrypt(rawKey, enc);   
        return new String(result);   
    }   
  
    /**
     * 
     * TODO(获取秘匙)
     * @Title: getRawKey
     * @return byte[]
     * @Exception
     */
    private static byte[] getRawKey(byte[] seed) throws Exception {   
//        KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
//        // SHA1PRNG ǿ
//        SecureRandom sr = null;   
////        if (android.os.Build.VERSION.SDK_INT >=  17) {  
////            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");  
////          } else {  
////            sr = SecureRandom.getInstance("SHA1PRNG");  
////          }   
////        sr.setSeed(seed);   
//        sr = new SecureRandom(seed);
//        kgen.init(KeyLength, sr); //256 bits or 128 bits,192bits
//        SecretKey skey = kgen.generateKey();   
//        byte[] raw = skey.getEncoded();   
//        return raw;   
    	KeyGenerator kgen = KeyGenerator.getInstance("AES");

		kgen.init(128, new SecureRandom(seed));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		return enCodeFormat;
    }   
  
    /**
     *    
     * TODO(根据密匙加密成Byte数组)
     * @Title: encrypt
     * @return byte[]
     * @Exception
     */
    private static byte[] encrypt(byte[] key, byte[] src) throws Exception {   
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");   
        Cipher cipher = Cipher.getInstance(CipherMode);   
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);   
        byte[] encrypted = cipher.doFinal(src);   
        return encrypted;   
    }   
    /**
     *    
     * TODO(根据密匙解密成Byte数组)
     * @Title: decrypt
     * @return byte[]
     * @Exception
     */
    private static byte[] decrypt(byte[] key, byte[] encrypted) throws Exception {   
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");   
        Cipher cipher = Cipher.getInstance(CipherMode);   
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);   
        byte[] decrypted = cipher.doFinal(encrypted);   
        return decrypted;   
    }   

    /** 字节数组转成16进制字符串 **/
    public static String byte2hex(byte[] b) { // 一个字节的数,
        StringBuffer sb = new StringBuffer(b.length * 2);
        String tmp = "";
        for (int n = 0; n < b.length; n++) {
            // 整数转成十六进制表示
            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        return sb.toString(); // 转成字符串

    }
 
    /** 将hex字符串转换成字节数组 **/
    private static byte[] hex2byte(String inputString) {
        if (inputString == null || inputString.length() < 2) {
            return new byte[0];
        }
        int l = inputString.length() / 2;
        byte[] result = new byte[l];
        for (int i = 0; i < l; ++i) {
            String tmp = inputString.substring(2 * i, 2 * i + 2);
            result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
        }
        return result;
    }

}

测试代码:

public class TestAES2 extends AndroidTestCase { // String src = "{'userid':'111'}"; //需加密字段 String key = "7e08ecf02a4f4cbb";  //秘钥 String dest = null;  //加密字符 public void testEncrypt(){ try { dest = AESCipher.encrypt(key, src); System.out.println(dest); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

求大神们告知下原因,困扰了好久了问题实在没办法了


举报
Neo_D
发帖于3年前 3回/2K+阅
共有3个答案 最后回答: 3年前
public static void main(String[] args) throws Exception {
        String key = "1234567890123456";
        String str = "12345678";
        byte[] keyByte = key.getBytes();
        byte[] dataByte = str.getBytes();
        byte[] ans = encrypt(dataByte, keyByte);
        //base64返回
        //System.out.println((new sun.misc.BASE64Encoder()).encodeBuffer(ans));
        //16进制返回
        System.out.println(byte2hex(ans));
    }
    
    /** 字节数组转成16进制字符串 **/
    public static String byte2hex(byte[] b) { // 一个字节的数,
        StringBuffer sb = new StringBuffer(b.length * 2);
        String tmp = "";
        for (int n = 0; n < b.length; n++) {
            // 整数转成十六进制表示
            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        return sb.toString(); // 转成字符串
 
    }
    
    //加密
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, k);
        return cipher.doFinal(data);
    }
    
    public static Key toKey(byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, "AES");
        return secretKey;
    }

这是我写的也是和他后台一样的加密代码,你自己研究一下,你可以自己写加密,然后看和他的密文是不是一样


引用一下此答案就行了






--- 共有 1 条评论 ---
Neo_D太感谢了 亲(づ ̄3 ̄)づ╭❤~ 3年前 回复

密码学代码注意 2 点:

1. 数据和密钥应当是原始的字节类型

2. AES 标准提供了用于验证的明文/密文对,不应当用什么在线网站。

主要是服务端的界面就是按照这个网站的标准来解密的,我Android端的对称不了,所以想请请大神看看怎么修改下我这里面的代码,在线网站上解密方式就是:AES  ECB模式密钥长度128bit 不偏移 无补码 加密结果编码方式为十六进制
--- 共有 1 条评论 ---
拉风的道长那你就让服务端的人看看到底哪里错了。他们应该很熟悉。 3年前 回复
顶部