我有一个运行良好的java代码
public static String encrypt(String message, String sercretKey)
{
String base64EncryptedString = "";
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digestOfPassword = md.digest(sercretKey.getBytes("utf-8"));
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
byte[] iv = Arrays.copyOf(digestOfPassword, 16);
SecretKey key = new SecretKeySpec(keyBytes, "AES");
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, ivParameterSpec);
byte[] plainTextBytes = message.getBytes("utf-8");
byte[] buf = cipher.doFinal(plainTextBytes);
byte[] base64Bytes = Base64.getEncoder().encode(buf);
base64EncryptedString = new String(base64Bytes);
return base64EncryptedString;
}
我试着用下面的代码在PHP中重新创建上面的代码
function encryptTest($sSecretKey,$sValue)
{
$key = hash('sha256', $sSecretKey,false);
$key = utf8_encode($key);
$key = substr($key, 0, 24);
$iv = substr($key, 0, 16);
$data = $sValue;
$outEnc = openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($outEnc);
}
但结果却不一样。我错过了什么。
(Same问题类型在StackOverflow中可用,但指向我的问题)
1条答案
按热度按时间bzzcjhmw1#
存在以下问题:
hash()
中的第三个参数从false
切换为true
。"AES-192-CBC"
(而不是"AES-256-CBC"
)。utf8_encode()
调用将被删除,因为这会损坏键。通过这些改变,两个代码提供相同的密文。
安全性:
使用SHA 256作为密钥派生是不安全的。请改用Argon 2或PBKDF 2之类的专用算法。此外,使用密钥(或密钥的一部分)作为IV也是不安全的,因为它会导致密钥/IV对的重用。相反,应针对每次加密应用随机生成的IV。