我的任务是将此代码移植到Java:
define('SALT', 'my_salt');
function auth_encrypt($text){
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
我已经用Java实现了这一点,这是我目前所知道的最好的方法,但我既不是加密专家,也不是PHP专家(充其量是新手)。有人能帮我弄清楚如何完成下面的块,这样我在Java中的输出就和他们在PHP中的输出一样吗?
byte[] sessionKey = Base64.encodeBase64("my_salt".getBytes());
byte[] iv = Base64.encodeBase64("WHAT-GOES-HERE??".getBytes());
byte[] plaintext = rawText.getBytes();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext);
return new String(ciphertext, "UTF8");
ECB模式与CBC模式不同。由于ECB模式不使用初始化向量(IV),因此不必将其传递给Cipher#init
。
但这并不能解决您的问题,因为MCRYPT_RIJNDAEL_256
是块大小为256位的Rijndael,而AES是块大小128位的Rijindael。默认的安全提供程序通常不会在Java中提供Rijndael,因此您将不得不使用非标准的提供程序,如BouncyCastle(示例)。
安全注意事项:
- 永远不要使用ECB模式,因为它在语义上不安全
- CBC模式提供了语义安全性,但只能使用不可预测的(随机读取)IV。IV不一定是秘密的,所以你可以在解密前将其预处理到密文中并切片
- 对密文进行身份验证可以防止许多攻击。您可以使用GCM或EAX等身份验证模式,也可以应用HMAC-SHA256等具有强大MAC功能的先加密后MAC方案