Java 中的传统加密和 PHP 中的解密
Legacy encryption in Java and decryption in PHP
我正在尝试使用 PHP 加密字符串,结果与遗留 Java 代码相同。
Java代码:
public static SecretKeySpec createSecretKey(String mKey) {
SecretKeySpec secretKey = null;
MessageDigest sha = null;
try {
byte[] key = mKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException ex) {
System.out.println("- createSecretKey > NoSuchAlgorithmException:" + ex.getMessage());
} catch (UnsupportedEncodingException ex) {
System.out.println("- createSecretKey > UnsupportedEncodingException:" + ex.getMessage());
} catch (Exception ex) {
System.out.println("- createSecretKey > Exception:" + ex.getMessage());
}
return secretKey;
}
public static String encryptAES(String stringToEncrypt, SecretKeySpec secretKey) { //Rijndael
String encryptedString = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
encryptedString = Base64.encodeBase64String(cipher.doFinal(stringToEncrypt.getBytes("UTF-8")));
} catch (Exception ex) {
System.out.println("- encryptAES > Exception: " + ex.getMessage());
}
return encryptedString;
}
现在我想获得与 PHP 相同的结果。
例如:
- 键 => 1234
- 输入字符串 => oneString
- 所需的输出字符串 => whx4s8e6p1erYtsIaFO7qA==
我这样做了 PHP 代码,但结果是错误的。
$key = "Cup45ZD7";
$o = "19uzJrsE";
echo getEncrypt(pkcs5_pad($o,16),$key) ;
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
function getEncrypt($sStr, $sKey) {
return base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
($sKey),
$sStr,
MCRYPT_MODE_ECB
)
);
}
有什么想法吗?
您需要使用相同的密钥派生:
- 从 "key"
获取 SHA-1 哈希
- 使用散列的前 16 个字节作为实际密钥
以下更改会产生所需的结果
echo getEncrypt(pkcs5_pad($o, 16), substr(sha1($key, true), 0, 16));
我正在尝试使用 PHP 加密字符串,结果与遗留 Java 代码相同。
Java代码:
public static SecretKeySpec createSecretKey(String mKey) {
SecretKeySpec secretKey = null;
MessageDigest sha = null;
try {
byte[] key = mKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException ex) {
System.out.println("- createSecretKey > NoSuchAlgorithmException:" + ex.getMessage());
} catch (UnsupportedEncodingException ex) {
System.out.println("- createSecretKey > UnsupportedEncodingException:" + ex.getMessage());
} catch (Exception ex) {
System.out.println("- createSecretKey > Exception:" + ex.getMessage());
}
return secretKey;
}
public static String encryptAES(String stringToEncrypt, SecretKeySpec secretKey) { //Rijndael
String encryptedString = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
encryptedString = Base64.encodeBase64String(cipher.doFinal(stringToEncrypt.getBytes("UTF-8")));
} catch (Exception ex) {
System.out.println("- encryptAES > Exception: " + ex.getMessage());
}
return encryptedString;
}
现在我想获得与 PHP 相同的结果。
例如:
- 键 => 1234
- 输入字符串 => oneString
- 所需的输出字符串 => whx4s8e6p1erYtsIaFO7qA==
我这样做了 PHP 代码,但结果是错误的。
$key = "Cup45ZD7";
$o = "19uzJrsE";
echo getEncrypt(pkcs5_pad($o,16),$key) ;
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
function getEncrypt($sStr, $sKey) {
return base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
($sKey),
$sStr,
MCRYPT_MODE_ECB
)
);
}
有什么想法吗?
您需要使用相同的密钥派生:
- 从 "key" 获取 SHA-1 哈希
- 使用散列的前 16 个字节作为实际密钥
以下更改会产生所需的结果
echo getEncrypt(pkcs5_pad($o, 16), substr(sha1($key, true), 0, 16));