PHP AES-256-CBC加密数据与JAVA AES/CBC/PKCS5PADDING不同 &g



我有一个完美的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);
}

但显示不同的结果。我错过了什么

(相同类型的问题可在StackOverflow,但指出我的问题)

有以下问题:

  • 在PHP代码中,当前返回的键是十六进制编码。相反,它必须作为字节串返回。为此,必须将hash()中的第三个参数从false切换为true
  • Java代码中使用192位密钥,即AES-192。因此,在PHP代码中必须应用"AES-192-CBC"(而不是"AES-256-CBC")。
  • PHP代码中的utf8_encode()调用将被删除,因为这会破坏密钥。

通过这些更改,两个代码提供相同的密文。

安全性:
使用SHA256作为密钥派生是不安全的。相反,可以使用专用算法,如Argon2或PBKDF2。此外,使用密钥(或它的一部分)作为IV是不安全的,因为它会导致密钥/IV对的重用。相反,应该对每个加密应用随机生成的IV。

最新更新