记AES加密在linux系统每次都不一样的问题
在项目中通常会用到AES的加密方法,具体代码如下
package com.mt.demo.client.utils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Component;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
/**
* AESUtils
*
* @author mt.luo
* @description: AES加密
*/
@Slf4j
@Component
public class AESUtils {
private final String aesSeed = "ada46ab5da824b96a18409c49dc91dc2";
private final String algorithm = "SHA-256";
private final String AES = "AES";
private final String cipher = "AES/ECB/PKCS7Padding";
private final String provider = "BC";
/**
* convert to byte[]
*
* @param key key
* @return byte[]
* @throws NoSuchAlgorithmException
*/
private byte[] toHash256(String key) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance(this.algorithm);
messageDigest.update(key.getBytes());
return messageDigest.digest();
}
/**
* parseHexStrToByte
*
* @param hexStr hexStr
* @return byte
*/
private byte[] parseHexStrToByte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* parseByteToHexStr
*
* @param bytes bytes
* @return String
*/
private String parseByteToHexStr(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
stringBuilder.append(hex.toUpperCase());
}
return stringBuilder.toString();
}
/**
* 获取密钥
*
* @param seed seed
* @return SecretKeySpec
* @throws NoSuchAlgorithmException NoSuchAlgorithmException
*/
private SecretKeySpec getSecretKeySpec(String seed) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(this.AES);
SecureRandom secureRandom = new SecureRandom(this.toHash256(seed));
keyGenerator.init(256, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
byte[] encode = secretKey.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(encode, this.AES);
Security.addProvider(new BouncyCastleProvider());
return secretKeySpec;
}
/**
* 加密
*
* @param data data
* @return String
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws NoSuchPaddingException
* @throws UnsupportedEncodingException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public String encrypt(String data) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
SecretKeySpec secretKeySpec = this.getSecretKeySpec(this.aesSeed);
Cipher cipher = Cipher.getInstance(this.cipher, this.provider);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return this.parseByteToHexStr(Base64.getEncoder().encode(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8.name()))));
}
}
然后这样使用在windows系统的时候没有问题,而将程序部署到Linux则发现每次加密之后获取的加密字符串都不同,也无法解密,重写获取密钥部分的代码
/**
* 获取密钥
*
* @param seed seed
* @return SecretKeySpec
* @throws NoSuchAlgorithmException NoSuchAlgorithmException
*/
private SecretKeySpec getSecretKeySpec(String seed) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(this.AES);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(this.toHash256(seed));
keyGenerator.init(256, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
byte[] encode = secretKey.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(encode, this.AES);
Security.addProvider(new BouncyCastleProvider());
return secretKeySpec;
}