今天需要对接一个java系统中的接口,对方使用了AES加密,根据对方描述基本可以确定对方用的是AES-ECB-128的加密方式,然后使用PKCS5的对齐方式。
我方需要使用openssl_decrypt进行解密,但是在这个过程中死活都无法进行解密。
最后用了一个很奇特的方式进行解密了。。。
先看下java的代码吧:
public static String encrypt(String content, String password) {
try {
String ENCRYPT_CHARSET = "UTF-8";
Security.addProvider(new sun.security.provider.Sun());
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", new sun.security.provider.Sun());
KeyGenerator kgen = KeyGenerator.getInstance("AES");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES"); // 创建密码器
byte[] byteContent = content.getBytes(ENCRYPT_CHARSET);
cipher.init(Cipher.ENCRYPT_MODE, key); // 初始化
byte[] result = cipher.doFinal(byteContent);
if (result != null && result.length > 0) {
/*
* 注意:
* return new String(result,ENCRYPT_CHARSET);
* 会出现javax.crypto.IllegalBlockSizeException:
* Input length must be multiple of 16 when decrypting with padded cipher
* 加密后的byte数组是不能强制转换成字符串的,
* 字符串和byte数组在这种情况下不是互逆的;
* 需要将二进制数据转换成十六进制表示
*/
return parseByte2HexStr(result);
}
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
} catch(NoSuchPaddingException e) {
e.printStackTrace();
} catch(InvalidKeyException e) {
e.printStackTrace();
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
} catch(IllegalBlockSizeException e) {
e.printStackTrace();
} catch(BadPaddingException e) {
e.printStackTrace();
}
return null;
}
以上可以看出,java使用了aes加密,然后将加密后的二进制数据转换成了十六进制字符串;
然后再看下我方的解密代码吧。。。
userObj=JAVA_SECRETTEXT;userObj=hex2bin(userObj);appkey=substr(openssl_digest(openssl_digest(appkey, 'sha1', true), 'sha1', true), 0, 16);deData=openssl_decrypt(userObj, 'aes-128-ecb',appkey, OPENSSL_RAW_DATA , '');
这里注意一下$appkey这行的代码,对解密秘钥进行了2次openssl_digest计算,也就是2次的sha1信息摘要计算,然后再取前16位字符串,就可以正常解密了。。
简直无语。。。。
文章评论