参考文章:
https://www.cnblogs.com/linuxcat/p/14494630.html
https://www.cnblogs.com/niuu/p/10107212.html
https://blog.csdn.net/u012119316/article/details/111193890
python环境 python3.7.5
安装包: pip install pycryptodome
很重要
python版本的算法有个问题,就是不能加密中文
代码
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad
from binascii import b2a_hex, a2b_hex
import hashlib
'''
pip install pycryptodome
'''
class AESEncrypt:
def __init__(self, key, iv):
self.key = bytes.fromhex(self.get_sha1png_key(key))
self.iv = iv.encode('utf-8')
self.mode = AES.MODE_CBC
def encrypt(self, text):
cryptor = AES.new(self.key, self.mode, self.iv)
text_pad = self.add_to_16(text)
ciphertext = cryptor.encrypt(text_pad)
return b2a_hex(ciphertext).upper().decode(encoding="utf-8")
def add_to_16(self, text):
return pad(text.encode('utf-8'), 16, style='pkcs7')
def decrypt(self, text):
base_text = a2b_hex(text)
cryptor = AES.new(self.key, self.mode, self.iv)
plain_text = cryptor.decrypt(base_text)
ne = unpad(plain_text, 16, 'pkcs7').decode('utf-8')
return ne
def get_sha1png_key(self, key):
'''[summary]
encrypt key with SHA1PRNG
same as java AES crypto key generator SHA1PRNG
Arguments:
key {[string]} -- [key]
Returns:
[string] -- [hexstring]
'''
signature = hashlib.sha1(key.encode()).digest()
signature = hashlib.sha1(signature).digest()
return ''.join(['%02x' % i for i in signature]).upper()[:32]
if __name__ == '__main__':
aes_encrypt = AESEncrypt(key='key', iv='aaaaaaaaaaaaaaaa') # 初始化key和IV
text = '中文加密234567890'
sign_data = aes_encrypt.encrypt(text)
print(sign_data)
data = aes_encrypt.decrypt(sign_data)
print(data)
运行结果
64ECC8FB6DA4D0A8D026CF7CEACBF7A09D34920E5C44DAB018A4B7B9A00AD1B8
中文加密234567890
java版本的
package top.fuly.springboot_13_utils.java_py_aes;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
public class EncryptUtil {
private static final String IV_DEFAULT = "aaaaaaaaaaaaaaaa";
private static final String AES = "AES";
private static final String CYPHER_MODE = "AES/CBC/NoPadding";
private static final String CHARSET = "utf-8";
private static final String ALGORITHM = "SHA1PRNG";
public static EncryptUtil me;
private EncryptUtil() {
// 单例
}
// 双重锁
public static EncryptUtil getInstance() {
if (me == null) {
synchronized (EncryptUtil.class) {
if (me == null) {
me = new EncryptUtil();
}
}
}
return me;
}
/**
* 使用AES加密算法经行加密(可逆)
*
* @param res
* 需要加密的密文
* @param key
* 秘钥
* @return
*/
public String AESencode(String res, String key) {
byte[] cyphertext;
try {
cyphertext = encrypt(key.getBytes(), IV_DEFAULT.getBytes(), res.getBytes(CHARSET));
// return Base64.getEncoder().encodeToString(cyphertext);
return parseByte2HexStr(cyphertext);
} catch (Exception e) {
// log.error("AESencode:", e);
}
return null;
}
/**
* 对使用AES加密算法的密文进行解密
*
* @param res
* 需要解密的密文
* @param key
* 秘钥
* @return
*/
public String AESdecode(String res, String key) {
// byte[] de_b64 = decrypt(key.getBytes(), IV_DEFAULT.getBytes(),
// Base64.getDecoder().decode(res));
byte[] de_b64 = decrypt(key.getBytes(), IV_DEFAULT.getBytes(), parseHexStr2Byte(res));
return new String(de_b64);
}
private byte[] encrypt(byte[] key, byte[] initVector, byte[] value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector);
byte[] enCodeFormat = genSha1prng(key);
SecretKeySpec skeySpec = new SecretKeySpec(enCodeFormat, AES);
Cipher cipher = Cipher.getInstance(CYPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
int blockSize = cipher.getBlockSize();
byte[] plaintext = padding(value, blockSize);
return cipher.doFinal(plaintext);
} catch (Exception ex) {
// log.error("encrypt:", ex);
}
return null;
}
private byte[] decrypt(byte[] key, byte[] initVector, byte[] encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector);
byte[] enCodeFormat = genSha1prng(key);
SecretKeySpec skeySpec = new SecretKeySpec(enCodeFormat, AES);
Cipher cipher = Cipher.getInstance(CYPHER_MODE);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
return unpadding(cipher.doFinal(encrypted));
} catch (Exception ex) {
// log.error("decrypt:", ex);
}
return null;
}
private byte[] genSha1prng(byte[] key) throws NoSuchAlgorithmException {
KeyGenerator kgen = KeyGenerator.getInstance(AES);
SecureRandom secureRandom = SecureRandom.getInstance(ALGORITHM);
secureRandom.setSeed(key);
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
return enCodeFormat;
}
private byte[] padding(byte[] value, int blockSize) {
int plaintextLength = value.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(value, 0, plaintext, 0, value.length);
return plaintext;
}
private byte[] unpadding(byte[] bytes) {
int i = bytes.length - 1;
while (i >= 0 && bytes[i] == 0) {
--i;
}
return Arrays.copyOf(bytes, i + 1);
}
/** 将16进制转换为二进制 */
private byte[] parseHexStr2Byte(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;
}
/** 将二进制转换成16进制 */
private String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static void main(String[] args) {
EncryptUtil a = EncryptUtil.getInstance();
String aeSencode = a.AESencode("中文加密234567890", "key");
System.out.println(aeSencode);
System.out.println(a.AESdecode(aeSencode,"key"));
}
}
运行结果:
64ECC8FB6DA4D0A8D026CF7CEACBF7A0318339DB7E1BDF754836F5DC1BFF9873
中文加密234567890