![](/img/trans.png)
[英]Translation of PHP openssl_decrypt/encrypt => to Java AES 256
[英]Java javax.crypto and PHP openssl_decrypt is not identical
我正在将Java解密程序代码移植到PHP。 我有3个文件:
看到这里链接
我在Java中使用javax.crypto包,使用AES / CBC / NoPadding(128)算法来解密数据。 在PHP中,我使用openssl扩展
PHP版本7.1.0 PHP信息(openssl):
我的代码示例:
我的Java代码:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.file.Files;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
File AesKeyFile = new File("./Cipher2PHP/aes.key");
File InitializationVectorFile = new File("./Cipher2PHP/initialization.vector");
File EncryptedDataFile = new File("./Cipher2PHP/encrypted.data");
byte[] AesKeyData = Files.readAllBytes(AesKeyFile.toPath());
byte[] InitializationVectorData = Files.readAllBytes(InitializationVectorFile.toPath());
byte[] EncryptedData = Files.readAllBytes(EncryptedDataFile.toPath());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(AesKeyData, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(InitializationVectorData));
byte[] result = cipher.doFinal(EncryptedData);
String decrypted = new String(result);
System.out.printf("Your data: %s\n", decrypted);
}
}
我的可移植PHP代码
<?php
$AesKeyData = file_get_contents('./Cipher2PHP/aes.key');
$InitializationVectorData = file_get_contents('./Cipher2PHP/initialization.vector');
$EncryptedData = file_get_contents('./Cipher2PHP/encrypted.data');
$decrypted = openssl_decrypt(
$EncryptedData,
'AES-128-CBC',
$AesKeyData,
OPENSSL_NO_PADDING,
$InitializationVectorData
);
printf("Your data: %s\n", $decrypted);
Java代码根据需要工作。 PHP代码不匹配。
Java代码输出:
Your data: My very secure data. Very secure
Process finished with exit code 0
PHP代码输出:
Your data: �j��2��䈤�n�h�/sEH�,/-��-�^[
Process finished with exit code 0
Base64编码的数据:
PHP:
Base64 AES Key: "Kl/LF5HSL7YCRbPYNp7QssJzcVY/vx88nt9rEYJaXQo="
Base64 InitializationVector: "QXF/8HO4te38LhhuFP9+hA=="
Base64 EncryptedData: "eA1w+ysqsHIdaXsQRSgt9nLPDj7ILcqyZdCW3wDBcy0="
Decrypted Result: "xmqJ0TKgx+SIpP1u/hNoyS9zRUjEAAEsLy251S2hXls="
Java的:
Base64 AES Key: "Kl/LF5HSL7YCRbPYNp7QssJzcVY/vx88nt9rEYJaXQo="
Base64 InitializationVector: "QXF/8HO4te38LhhuFP9+hA=="
Base64 EncryptedData: "eA1w+ysqsHIdaXsQRSgt9nLPDj7ILcqyZdCW3wDBcy0="
Decrypted Result: "TXkgdmVyeSBzZWN1cmUgZGF0YS4gVmVyeSBzZWN1cmU="
控制台中的文件:
./Cipher2PHP mac$ file -I *
aes.key: application/octet-stream; charset=binary
initialization.vector: application/octet-stream; charset=binary
encrypted.data: application/octet-stream; charset=binary
./Cipher2PHP mac$ xxd aes.key
0000000: 2a5f cb17 91d2 2fb6 0245 b3d8 369e d0b2 *_..../..E..6...
0000010: c273 7156 3fbf 1f3c 9edf 6b11 825a 5d0a .sqV?..<..k..Z].
./Cipher2PHP mac$ xxd initialization.vector
0000000: 4171 7ff0 73b8 b5ed fc2e 186e 14ff 7e84 Aq..s......n..~.
./Cipher2PHP mac$ xxd encrypted.data
0000000: 780d 70fb 2b2a b072 1d69 7b10 4528 2df6 x.p.+*.r.i{.E(-.
0000010: 72cf 0e3e c82d cab2 65d0 96df 00c1 732d r..>.-..e.....s-
./Cipher2PHP mac$ xxd -b aes.key
0000000: 00101010 01011111 11001011 00010111 10010001 11010010 *_....
0000006: 00101111 10110110 00000010 01000101 10110011 11011000 /..E..
000000c: 00110110 10011110 11010000 10110010 11000010 01110011 6....s
0000012: 01110001 01010110 00111111 10111111 00011111 00111100 qV?..<
0000018: 10011110 11011111 01101011 00010001 10000010 01011010 ..k..Z
000001e: 01011101 00001010 ].
./Cipher2PHP mac$ xxd -b initialization.vector
0000000: 01000001 01110001 01111111 11110000 01110011 10111000 Aq..s.
0000006: 10110101 11101101 11111100 00101110 00011000 01101110 .....n
000000c: 00010100 11111111 01111110 10000100 ..~.
./Cipher2PHP mac$ xxd -b encrypted.data
0000000: 01111000 00001101 01110000 11111011 00101011 00101010 x.p.+*
0000006: 10110000 01110010 00011101 01101001 01111011 00010000 .r.i{.
000000c: 01000101 00101000 00101101 11110110 01110010 11001111 E(-.r.
0000012: 00001110 00111110 11001000 00101101 11001010 10110010 .>.-..
0000018: 01100101 11010000 10010110 11011111 00000000 11000001 e.....
000001e: 01110011 00101101
在Java中,要使用的AES版本(128、192或256位)由您提供的密钥的长度确定,该长度必须恰好是这些长度之一。
在PHP中,您可以在openssl_decrypt
或openssl_encrypt
的method参数中明确指定要使用的AES版本,例如“ aes-128-cbc”。 然后,PHP将截断或以零字节扩展您提供的密钥,使其为所需的长度。
您使用的是32字节(256位)密钥,因此您的Java代码使用的是AES-256。 但是,您的PHP代码指定了“ AES-128-CBC”,因此您使用的是其他版本。
要使PHP版本的行为类似于Java版本,请openssl_decrypt
的调用中的方法字符串更改为'aes-256-cbc'
。
为了使Java版本的行为类似于PHP版本(我不希望这样做,但是为了完整起见我将其包括在内),请复制密钥的前16个字节,并且仅在创建SecretKeySpec
对象时使用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.