PHP中Java解密中的AES 128加密
我一直在尝试使用AES-128 CBC解密一个字符串,它最初是使用JavaAES加密加密的。在java中,使用了PKCS7填充。我曾尝试使用类似的PHP代码进行加密和解密。但是我得到了不同的结果 我的Java代码PHP中Java解密中的AES 128加密,java,php,android,encryption,aes,Java,Php,Android,Encryption,Aes,我一直在尝试使用AES-128 CBC解密一个字符串,它最初是使用JavaAES加密加密的。在java中,使用了PKCS7填充。我曾尝试使用类似的PHP代码进行加密和解密。但是我得到了不同的结果 我的Java代码 import java.security.MessageDigest; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.spec.IvP
import java.security.MessageDigest;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
/**
* @author vipin.cb , vipin.cb@experionglobal.com <br>
* Sep 27, 2013, 5:18:34 PM <br>
* Package:- <b>com.veebow.util</b> <br>
* Project:- <b>Veebow</b>
* <p>
*/
public class AESCrypt {
private final Cipher cipher;
private final SecretKeySpec key;
private AlgorithmParameterSpec spec;
public static final String SEED_16_CHARACTER = "U1MjU1M0FDOUZ.Qz";
public AESCrypt() throws Exception {
// hash password with SHA-256 and crop the output to 128-bit for key
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(SEED_16_CHARACTER.getBytes("UTF-8"));
byte[] keyBytes = new byte[32];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
key = new SecretKeySpec(keyBytes, "AES");
spec = getIV();
}
public AlgorithmParameterSpec getIV() {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
IvParameterSpec ivParameterSpec;
ivParameterSpec = new IvParameterSpec(iv);
return ivParameterSpec;
}
public String encrypt(String plainText) throws Exception {
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
String encryptedText = new String(Base64.encode(encrypted,
Base64.DEFAULT), "UTF-8");
return encryptedText;
}
public String decrypt(String cryptedText) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT);
byte[] decrypted = cipher.doFinal(bytes);
String decryptedText = new String(decrypted, "UTF-8");
return decryptedText;
}
}
import java.security.MessageDigest;
导入java.security.spec.AlgorithmParameterSpec;
导入javax.crypto.Cipher;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.SecretKeySpec;
导入android.util.Base64;
/**
*@author vipin.cb,vipin。cb@experionglobal.com
*2013年9月27日下午5:18:34
*包:-com.veebow.util
*项目:-Veebow
*
*/
公共类七层密码{
专用最终密码;
私有最终SecretKeySpec密钥;
私有算法参数规范;
公共静态最终字符串SEED_16_CHARACTER=“U1MjU1M0FDOUZ.Qz”;
public AESCrypt()引发异常{
//使用SHA-256散列密码,并将输出裁剪为128位作为密钥
MessageDigest=MessageDigest.getInstance(“SHA-256”);
更新(SEED_16_CHARACTER.getBytes(“UTF-8”);
byte[]keyBytes=新字节[32];
System.arraycopy(digest.digest(),0,keyBytes,0,keyBytes.length);
cipher=cipher.getInstance(“AES/CBC/PKCS7Padding”);
key=新的SecretKeySpec(keyBytes,“AES”);
spec=getIV();
}
公共算法参数SPEC getIV(){
字节[]iv={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
IvParameterSpec IvParameterSpec;
ivParameterSpec=新的ivParameterSpec(iv);
返回ivParameterSpec;
}
公共字符串加密(字符串明文)引发异常{
cipher.init(cipher.ENCRYPT_模式,密钥,规范);
byte[]encrypted=cipher.doFinal(明文.getBytes(“UTF-8”);
String encryptedText=新字符串(Base64.encode)(加密,
Base64(默认),“UTF-8”);
返回加密文本;
}
公共字符串解密(字符串加密文本)引发异常{
cipher.init(cipher.DECRYPT_模式,密钥,规范);
byte[]bytes=Base64.decode(cryptedText,Base64.DEFAULT);
byte[]decrypted=cipher.doFinal(字节);
String decryptedText=新字符串(已解密,“UTF-8”);
返回解密文本;
}
}
以及我正在使用的等效PHP代码
<?php
class MCrypt {
private $iv = '0000000000000000'; #Same as in JAVA
private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA
function __construct() {
$this->key = hash('sha256', $this->key, true);
}
function encrypt($str) {
$iv = $this->iv;
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $iv);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}
function decrypt($code) {
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', '');
mcrypt_generic_init($td, $this->key, $iv);
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size('rijndael-128', 'cbc');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $str;
//return $this->strippadding($str);
}
/*
For PKCS7 padding
*/
private function addpadding($string, $blocksize = 16) {
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
$string = substr($string, 0, strlen($string) - $slast);
return $string;
} else {
return false;
}
}
}
$encryption = new MCrypt();
echo $encryption->encrypt('123456') . "<br/>";
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w==');
你的IV是不同的,一个值为零的字节不同于一个字符'0'
,该字符将转换为一个值为30
的十六进制字节或48进制字节(如果你假定为ASCII或UTF-8编码)。IV应该是什么。我给IV分配了16个空格,运气不好。我尝试在java中将字节iv转换为字符串,得到了长度为16的空字符串。我尝试用php加密,但没有任何运气。比较两种平台上IV的字节值。请记住,对称密码的输入和输出是以字节为单位的,并且已为密码预定义了字节顺序。您应该始终得到与平台无关的相同结果。因此,请确保输入到算法中的值在两个平台上是相同的。最好的方法是在执行加密操作之前以十六进制打印输入值。小心(字符)编码/解码问题!如果可能,请使用相同的字节数组测试算法本身的输入/输出。非常感谢owlstead。。我遵循了你提到的步骤。。谢谢你耐心地回答我的问题和这里的评论…爱你。谢谢。这正是我想要的。修复了我的钥匙和presto magico中的一个打字错误@ssdscott我很高兴它帮助了你,即使在2年前发布:)
<?php
class MCrypt {
private $hex_iv = '00000000000000000000000000000000'; # converted Java byte code in to HEX and placed it here
private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA
function __construct() {
$this->key = hash('sha256', $this->key, true);
//echo $this->key.'<br/>';
}
function encrypt($str) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}
function decrypt($code) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $this->strippadding($str);
}
/*
For PKCS7 padding
*/
private function addpadding($string, $blocksize = 16) {
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
$string = substr($string, 0, strlen($string) - $slast);
return $string;
} else {
return false;
}
}
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
}
$encryption = new MCrypt();
echo $encryption->encrypt('123456') . "<br/>";
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w==');