AESphpjava互转
java源代码加密php
<?php
class AesCrypt
{
//初始化向量
private$iv = '84195bd96a8a2e7f';
//Mcrypt算法
private$cipher = MCRYPT_RIJNDAEL_128;
//Mcrypt⽀持的加密模型特别适⽤于对⽂件进⾏加密。相⽐ ECB,它的安全性有明显提升。
private$mode = MCRYPT_MODE_CBC;
public function encrypt($str, $key = '')
{
$str = $this->addPKCS7Padding($str);
$encrypted = mcrypt_encrypt($this->cipher, $key, $str, $this->mode, $this->iv);
return$encrypted;
}
public function decrypt($code, $key = '')
{
$decrypted = mcrypt_decrypt($this->cipher, $key, $code, $this->mode, $this->iv);
$decrypted = $this->stripPKSC7Padding($decrypted);
return$decrypted;
}
protected function addPKCS7Padding($source)
{
$block = mcrypt_get_block_size($this->cipher, $this->mode);
$pad = $block - (strlen($source) % $block);
$char = chr($pad);
$source .= str_repeat($char, $pad);
return$source;
}
public function stripPKSC7Padding($source)
{
$char = substr($source, -1);
$num = ord($char);
$source = substr($source, 0, -$num);
return$source;
}
}
注意:php 的 mcrypt_簇在 7.1.0 版本中开始 deprecated,并在 7.2.0 版本中彻底废弃,可以增加@来抑制报错
mcrypt always pads data will the null ('\0') character to fill out to n * blocksize
mcrypt_簇和 openssl_族对应关系
注意 MCRYPT_RIJNDAEL_256 并不是 AES-256,如果想使⽤mcrypt_簇实现 AES-256,则你应该使⽤ MCRYPT_RIJNDAEL_128 算法+ 32 位的 key
MCRYPT_RIJNDAEL_128 & MCRYPT_MODE_CBC + 16位Key = openssl_encrypt(AES-128-CBC, 16位Key) = AES-128
MCRYPT_RIJNDAEL_128 & MCRYPT_MODE_CBC + 24位Key = openssl_encrypt(AES-192-CBC, 24位Key) = AES-192
MCRYPT_RIJNDAEL_128 & MCRYPT_MODE_CBC + 32位Key = openssl_encrypt(AES-256-CBC, 32位Key) = AES-256
java
/**
* AES加解密 for原创php代码
* ⾮PHP重构代码不要使⽤该⽅法
*/
@Slf4j
public class OgnvAesCrypt {
/**
* 使⽤固定长度密钥
*/
private static final int KEY_LENGTH = 16;
/**
* 算法/模式/填充⽅式
*/
private static final String AES_CIPHER = "AES/CBC/PKCS7Padding";
private static final String AES_ALGORITHM = "AES";
private static final IvParameterSpec IV = new IvParameterSpec("84195bd96a8a2e7f".getBytes()); static {
//support PKCS7Padding
if (Provider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
/**
* aes解密
* @param data 加密数据
* @param key 解密密钥
* @return null 参数不符合要求或解密失败
*/
public static byte[] decrypt(byte[] data, byte[] key) {
if (data == null || key == null) {
return null;
}
if (key.length != KEY_LENGTH) {
throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
}
try {
SecretKeySpec secretKey = new SecretKeySpec(key, AES_ALGORITHM);
byte[] enCodeFormat = Encoded();
SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, AES_ALGORITHM);
Cipher cipher = Instance(AES_CIPHER);
cipher.init(Cipher.DECRYPT_MODE, seckey, IV);
return cipher.doFinal(data);
} catch (Exception e) {
<("OgnvAesCrypt decrypt fail:{}", e.getMessage(), e);
}
return null;
}
/**
* aes加密
* @param data 需要加密的内容
* @param key 加密密钥
* @return参数不符合要求或加密失败
*/
public static byte[] encrypt(byte[] data, byte[] key) {
if (data == null || key == null) {
return null;
}
if (key.length != KEY_LENGTH) {
throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
}
try {
SecretKeySpec secretKey = new SecretKeySpec(key, AES_ALGORITHM);
byte[] enCodeFormat = Encoded();
SecretKeySpec seckey = new SecretKeySpec(enCodeFormat, AES_ALGORITHM);
Cipher cipher = Instance(AES_CIPHER);
cipher.init(Cipher.ENCRYPT_MODE, seckey, IV);
return cipher.doFinal(data);
} catch (Exception e) {
<("OgnvAesCrypt encrypt fail:{}", e.getMessage(), e);
}
return null;
}
}
AES 是 Rijndael ⼦集
AES has a fixed block size of 128 bits and a key size of 128, 192, or 256 bits,
whereas Rijndael can be specified with block and key sizes in any multiple of 32 bits, with a minimum of 128 bits and a maximum of 256 bits.
BouncyCastle 是⼀个提供了很多 Java标准库哈希算法和加密算法的第三⽅库
PKCS5Padding是不⽀持AES算法的,当 Instance("AES/CBC/PKCS5Padding") 时实际使⽤的是PKCS7Padding,可能是历史遗留问题
pkcs5 vs pkcs7
pkcs5是pkcs7的⼦集算法
pkcs5: blockSize固定为8byte
pkcs7: blockSize固定为 1~255byte
⽣成指定长度密钥
⼝令可以为任意长度,但是不同加密算法对密钥长度有严格要求
//⼝令
String password = "jksong";
//密钥⽣成器
KeyGenerator keyGenerator = Instance("AES");
//SHA1PRNG随机算法为:原始秘钥经过两次sha1加密
//php对应代码: substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 密钥位数);
SecureRandom secureRandom = Instance("SHA1PRNG");
secureRandom.Bytes());
//设置密钥的⼤⼩和随机源
keyGenerator.init(128, secureRandom);
//⽣成唯⼀秘钥
SecretKey secretKey = ateKey();
byte[] encoded = Encoded();
System.out.deHexString(encoded));
参考
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论