Java AES / CBC / PKCS5PADDING函数
public static String encrypt_key_data(String password, String message) {
//password = 4lt0iD3biT@2O17l8
//message = "{"key_id":"101","merchant_code":"65010A"}";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING", "SunJCE");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] hashedpassword = sha.digest(password.getBytes("UTF-8"));
hashedpassword = Arrays.copyOf(hashedpassword, 16);
SecretKeySpec key = new SecretKeySpec(hashedpassword, "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
byte[] encrypted;
encrypted = cipher.doFinal(message.getBytes());
return asHex(encrypted);
}
java函数结果值= 'bc26d620be9fa0d810e31e62b00a518f79524f6142b90550b9148d50a1ab94ba55671e68f6cf3ebc44dd6af12f566ee8'
PHP AES-256-CBC功能
function encrypt($password, $iv, $data) {
$password = '4lt0iD3biT@2O17l8';
$iv = 'AAAAAAAAAAAAAAAA';
$data = '{"key_id":"101","merchant_code":"65010A"}';
$encodedEncryptedData = (openssl_encrypt(($data), 'AES-256-CBC', fixKey(sha1($password)), OPENSSL_RAW_DATA, $iv));
print_r(bin2hex($encodedEncryptedData));
}
function fixKey($key) {
if (strlen($key) < 32) {
//0 pad to len 32
return str_pad("$key", 32, "0");
}
if (strlen($key) > 32) {
//truncate to 32 bytes
return substr($key, 0, 32);
}
return $key;
}
php函数结果值= 'cf20379c95a41429d4097f0ef7982c72a0d25c014cc09d93ba4a111bb9c11c38bc75d6c9f16cd9cb6545dc8c31560985'
我使用相同的密码和相同的IV,并且我已经阅读到AES / CBC / PKCS5PADDING与AES-256-CBC等效。但是为什么我的结果不同? 请告诉我我的错在哪里
============================================= < / p>
解决了。我需要hex2bin($key)
,然后使用密钥通过aes进行加密
答案 0 :(得分:0)
要执行 AES-256 ,您需要一个256位密钥,但是您只提供128位-两者均在Java中具有:
hashedpassword = Arrays.copyOf(hashedpassword, 16);
..并在PHP中具有:
if (strlen($key) > 32) {
//truncate to 32 bytes
return substr($key, 0, 32);
}
$key
是一个十六进制字符串,每位数只有4位(4 * 32 = 128)。
Java 会从提供的密钥中阻止密钥长度,因此您最终会用Java进行128位加密。当您提供有冲突的信息时,PHP / Openssl最终要执行的操作确实是个未知数。您需要 AES-256-CBC ,但仅提供128位密钥。
也,您不应使用简单的SHA1来从密码派生密钥。而是使用诸如pbkdf2之类的密钥派生函数,或者仅使用实际的二进制密钥。