内容简介:在项目开发中遇到AES加密解密的问题,因为一个参数问题卡了比较久,做个记录。并给出AES加密解密分别用Java、Python和C++的实现代码。AES加密算法即密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。AES加密算法涉及4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(
在项目开发中遇到AES加密解密的问题,因为一个参数问题卡了比较久,做个记录。并给出AES加密解密分别用 Java 、 Python 和C++的实现代码。
一、AES简介
AES加密算法即密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
AES加密算法涉及4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。
解密算法的每一步分别对应加密算法的逆操作,加解密所有操作的顺序正好是相反的。
二、AES加密解密-Java实现
/**
* PAD模式
* NoPadding
* PKCS7Padding
* PKCS5Padding
* PKCS1Padding
*/
private final String AES_PATTERN = "AES/CBC/NoPadding";
/**
* AES加密KEY参数值,16个字符
*/
private final String AES_KEY = "aaaaaaaaaaaaaaaa";
/**
* AES加密向量参数值,16个字符
*/
private final String AES_IV = "bbbbbbbbbbbbbbbb";
/**
* 字符编码
*/
private final String CHARSET_ISO ="ISO8859-1";
/**
* 解密
*
* @param content 要解密的文本内容,也可以直接替换成byte[]数组
* @param pattern 模式参数
* @param key 解密KEY值
* @param iv 解密向量值
* @param charSet 字符编码
* @return
*/
public String decrypt(String content, String pattern, String key,
String iv, String charSet) {
try {
Cipher cipher = Cipher.getInstance(pattern);
Key sKeySpec = new SecretKeySpec(key.getBytes(charSet), "AES");
cipher.init(Cipher.DECRYPT_MODE, sKeySpec,
generateIV(iv.getBytes(charSet)));
byte[] result = cipher.doFinal(content.getBytes(charSet));
return new String(result, charSet);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 加密
*
* @param content 要加密的文本内容,也可以直接替换成byte[]数组
* @param pattern 模式参数
* @param key 解密KEY值
* @param iv 解密向量值
* @param charSet 字符编码
* @return
*/
public String encrypt(String content, String pattern, String key,
String iv, String charSet) {
try {
Cipher cipher = Cipher.getInstance(pattern);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(charSet), "AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec,
new IvParameterSpec(iv.getBytes(charSet)));
byte[] encrypted = cipher.doFinal(content.getBytes(charSet));
return new String(encrypted, charSet);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 初始化向量参数
*
* @param iv
* @return
* @throws Exception
*/
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
1)关于为何用”ISO8859-1″的编码方式,见 Android AES加密报错处理 :
javax.crypto.IllegalBlockSizeException: error:1e00007b: Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
2)Padding参数要特别注意下
如果项目中配置文件用Python脚本加密了,解密要使用Java代码来实现,需要注意下Python脚本使用的Padding模式,就是因为在Python脚本的实现中,没有设置Padding参数,Java代码中设置了PKCS5Padding,使得解密一直出异常。如果是输出下面的异常,查下Padding参数是否设置正确。
java.lang.RuntimeException: javax.crypto.BadPaddingException: error:1e000065: Cipher functions:OPENSSL_internal:BAD_DECRYPT java.lang.RuntimeException: javax.crypto.BadPaddingException: error:1e000065: Cipher functions:OPENSSL_internal:BAD_DECRYPT at java.lang.Thread.run(Thread.java:776) Caused by: javax.crypto.BadPaddingException: error:1e000065: Cipher functions:OPENSSL_internal:BAD_DECRYPT at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method) at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:568) at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:350) at javax.crypto.Cipher.doFinal(Cipher.java:2056) ... 4 more
三、AES加密解密-Python实现
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from binascii import b2a_hex, a2b_hex
from Crypto.Cipher import AES
import struct
import os
MODE = AES.MODE_CBC
KEY = ‘aaaaaaaaaaaaaaaa’
IV = ‘bbbbbbbbbbbbbbbb’
def aes_encrypt(content):
cryptor = AES.new(KEY, MODE, IV)
# 密钥key,长度:16(AES-128)、24(AES-192)、32(AES-256)
length = 16
count = len(content)
if count < length:
add = (length – count)
content = content + (‘\0’ * add)
elif count > length:
add = (length – (count % length))
content = content + (‘\0’ * add)
encrypted = cryptor.encrypt(content)
return encrypted
def aes_decrypt(content):
cryptor = AES.new(KEY, MODE, IV)
decrypt = cryptor.decrypt(content)
return decrypt
def encrypt_file(input, output):
if not os.path.exists(input):
print(‘encrypt_file: input file %s not exits.’ % input)
return
print(“encrypt_file file %s to %s” % (input, output))
with open(input, ‘r’) as origin:
data = origin.read()
encrypt_content = aes_encrypt(data)
with open(output, ‘w’) as encrypt:
encrypt.write(encrypt_content)
def decrypt_file(input, output):
if not os.path.exists(input):
print(‘decrypt_file: input file %s not exits.’ % input)
return
print(“decrypt_file file %s to %s” % (input, output))
with open(input, ‘r’) as origin:
data = origin.read()
decrypt_content = aes_decrypt(data)
with open(output, ‘w’) as decrypt:
decrypt.write(decrypt_content)
四、AES加密解密-C++实现
/**
* 加密
*/
gbool ConfigEncrypt(char *pData, int nLen, char **ppOutData, int *pnOutLen,
char *KEY, char *VEC) {
if (pData == NULL) {
return gfalse;
}
char ivec[16] ={0} ;
AES_KEY aes_ks1;
int nRet = 0;
char *pInData = NULL;
int nBlock = 0;
char *pOutData = NULL;
int nOutLen = 0;
if (pData <= 0) {
return (gfalse);
}
int nTmpLen = 16 - nLen % 16;
pInData = (char*)malloc(nLen + 64);
memset(pInData, 0, nLen + 64);
memcpy(pInData, pData, nLen);
pOutData = (char*)malloc(nLen + 64);
memset(pOutData, 0, nLen + 64);
memcpy(ivec, VEC, 16u);
nLen += nTmpLen;
nRet = AES_set_encrypt_key((const unsigned char *)KEY, 128, &aes_ks1);
AES_cbc_encrypt((const unsigned char *)pInData, (unsigned char *)pOutData,
nLen + 16, &aes_ks1, (unsigned char *)ivec, AES_ENCRYPT);
free(pInData);
nOutLen = nLen + 16;
*ppOutData = pOutData;
*pnOutLen = nOutLen;
return (gtrue);
}
/**
* 解密
*/
gbool ConfigDecrypt(char *pData, int nLen, char **ppOutData, int *pnOutLen,
char *KEY, char *VEC) {
if (pData == NULL || nLen == 0) {
return gfalse;
}
gbool bRet = gfalse;
char ivec[16] ={0} ;
AES_KEY aes_ks1 = {0};
int nRet = 0;
char *pTemp = NULL;
if (pData <= 0) {
return gfalse;
}
memcpy(ivec, VEC, sizeof(ivec));
nRet = AES_set_decrypt_key((const unsigned char *)KEY, 128, &aes_ks1);
pData = pData + 16;
char *pDstData = (char*)calloc(nLen + 16, 1);
if (pDstData) {
AES_cbc_encrypt((const unsigned char *)pData, (unsigned char *)pDstData,
nLen - 16, &aes_ks1, (unsigned char *)ivec, AES_DECRYPT);
memcpy(pnOutLen, pDstData, 4);
char *pOutData = (char *)calloc((*pnOutLen) + 1, 1);
if (pOutData && *pnOutLen > 0)
{
memcpy(pOutData, pDstData + 4, *pnOutLen);
*ppOutData = pOutData;
bRet = gtrue;
}
free(pDstData);
pDstData = NULL;
}
return bRet;
}
五、参考资料
以上所述就是小编给大家介绍的《AES加密解密》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Out of their Minds
Dennis Shasha、Cathy Lazere / Springer / 1998-07-02 / USD 16.00
This best-selling book is now available in an inexpensive softcover format. Imagine living during the Renaissance and being able to interview that eras greatest scientists about their inspirations, di......一起来看看 《Out of their Minds》 这本书的介绍吧!