php实现AES/CBC/PKCS5Padding加密解密与java代码运行等到结果一致,php版本为5.6。期间尝试过很多方法得到的加密解密结果都与java的不一致,最后写出以下方法,亲测有效,主要原因就是php的填充方式一定要选对。
两种语言的密钥和偏移量需要一致。
java代码:
private static final String KEY_ALGORITHM = "AES";
private static String CHARSET_ENCODING = "UTF-8";
private static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
private String key;
private String iv;
public AESCrypt(String appSecret)
throws Exception
{
Utilities.isNotNull(appSecret, "appSecret");
if (appSecret.length() != 40) {
throw new Exception("appSecret长度不正确");
}
this.key = appSecret.substring(0, 24);
this.iv = appSecret.substring(24);
}
public String enAESCrypt(String sSrc)
throws Exception
{
Exception ex1;
try
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] raw = this.key.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(this.iv.getBytes());
cipher.init(1, skeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes(CHARSET_ENCODING));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
ex1=ex;
}throw new Exception("加密异常:" + ex1.getMessage());
}
public String deAESCrypt(String sSrc)
throws Exception
{
Exception ex1;
try
{
byte[] raw = this.key.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(this.iv.getBytes());
cipher.init(2, skeySpec, iv);
byte[] encrypted = Base64.decodeBase64(sSrc);
byte[] original = cipher.doFinal(encrypted);
return new String(original, CHARSET_ENCODING);
} catch (Exception ex) {
ex.printStackTrace();
ex1=ex;
}throw new Exception("解密异常:" + ex1.getMessage());
}
php版:
//AES加密
private function encrypt($encryptStr, $encryptKey,$localIV) {
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, $localIV);
mcrypt_generic_init($module, $encryptKey, $localIV);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($encryptStr) % $block); //Compute how many characters need to pad
$encryptStr .= str_repeat(chr($pad), $pad); // After pad, the str length must be equal to block or its integer multiples
$encrypted = mcrypt_generic($module, $encryptStr);
mcrypt_generic_deinit($module);
mcrypt_module_close($module);
return base64_encode($encrypted);
}
//AES解密
function decrypt($code,$key,$iv) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$str = mdecrypt_generic($td, base64_decode($code));
mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $this->strippadding($str);
}
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;
}
}
|