我正在创建一个调用第三方API的应用程序,他们提供了PHP代码,而我们需要的是Java代码。
PHP代码如下:
4
现在我将上述代码更改为java:
function encryptIt( $string ) {
$key = 'qJB0rGtIn5UB1xG03efyCp';
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encrypted = openssl_encrypt($string, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($encrypted . '::' . $iv);
}
实际上,我在加密技术上并不擅长,因此PHP代码创建了IV代码,但是在互联网上搜索后,我试图如上所述创建IV代码,
但是我得到的错误是:
private static String openssl_encrypt(String data, String strKey, String strIv) throws Exception {
SecureRandom randomSecureRandom = new SecureRandom();
Base64 base64 = new Base64();
Cipher ciper = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] ivv = new byte[ciper.getBlockSize()];
randomSecureRandom.nextBytes(ivv);
SecretKeySpec key = new SecretKeySpec(strKey.getBytes(), "AES");
IvParameterSpec iv = new IvParameterSpec(ivv, 0, ciper.getBlockSize());
// Encrypt
ciper.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encryptedCiperBytes = ciper.doFinal(data.getBytes());
String s = new String(base64.encode(encryptedCiperBytes));
System.out.println("Ciper : " + s);
return s;
}
请帮助我解决这个问题
已更新:
我将代码更新为:
java.security.InvalidKeyException: Invalid AES key length: 22 bytes
at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:509)
at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1038)
at javax.crypto.Cipher.init(Cipher.java:1393)
at javax.crypto.Cipher.init(Cipher.java:1327)
还是我得到的错误是:
java.security.InvalidKeyException:密钥大小非法
我的API提供程序说那就是关键!
答案 0 :(得分:3)
就像命运多{的mcrypt
一样,openssl_encrypt
允许使用大小错误的密钥。它不会拒绝此类密钥,而只是用零值字节(PHP中的"\0"
)填充密钥的其余部分。几乎所有高级语言的库都完全违反了任何良好的加密惯例。
这很可能是由于两个原因:
-256
命令中的openssl
)。因此,要复制有缺陷的PHP代码,您必须将密钥填充为零字节(直到数组长度为32个字节)。在Java中,如今通常使用可怕的Arrays.copyOf
执行此操作(因为它也右填充了零字节)。
请注意,IV当然仍将确保您的加密结果永远不匹配。相反,请尝试使用Java解密并使用相同的方案进行加密,以确保IV在最终代码中保持随机。
键绝不是字符串。密钥由位或(最好是)对存储在安全存储器中某处的密钥的引用组成。但是,密码是字符串,因此确实应该首选使用PKBDF2。
当然,要使用PBKDF2,需要: