对接中国移动互联网聚合API(必达消息能力、5G快签,认证能力),总结出来的有关AES经验:由于AES加密存在不同的加密模式、算法、数据填充方式等,在对第三方平台AES加密的数据进行解密时,需保证与加密的方式完全一致才行。若加解密方式不完全一致,则可能导致解密失败。
简介
AES(Advanced Encryption Standard)
是一种对称加密算法,它是目前应用最广泛的加密算法之一。AES算法具有高效性、安全性和可靠性,被广泛用于数据保护、网络通信以及安全传输等领域。本文将深入介绍AES加密算法的原理、使用步骤以及常见的加密模式和填充方案。
原理
AES加密算法使用分组密码的方式对数据进行加密和解密。它采用了迭代、替代和混淆的步骤,通过多轮操作对数据进行混淆和扩散,从而达到高强度的加密效果。
AES算法使用固定长度的密钥(128位、192位或256位)和固定长度的分组(128位)进行加密和解密。加密过程中,明文被分成多个128位的分组,然后通过多轮的迭代,每轮包括替代、置换和混淆步骤,最终得到密文。解密过程与加密过程相反,通过逆向操作将密文还原为明文。
AES算法的核心是S盒、轮密钥和线性变换等操作。S盒是一个固定的字节替代表,用于替换输入的字节值。轮密钥是通过密钥扩展算法生成的每一轮操作所需的子密钥。线性变换是通过有限域上的乘法和加法操作来扩散数据。
使用步骤
使用AES加密算法进行加密和解密的步骤如下:
- 选择合适的密钥长度:AES算法支持128位、192位和256位三种密钥长度。根据安全需求选择合适的密钥长度。
- 选择加密模式和填充方案:根据应用场景和需求选择合适的加密模式和填充方案。常见的加密模式有ECB、CBC、CTR等,常见的填充方案有PKCS7、PKCS5、NoPadding等。
- 密钥生成和扩展:根据选择的密钥长度生成密钥,并通过密钥扩展算法生成每一轮操作所需的子密钥。
- 分组处理:将待加密的明文按照分组长度(128位)进行划分,得到多个分组。
- 加密过程:对每个分组进行多轮的迭代操作,包括字节替代、行移位、列混淆和轮密钥加等步骤,最终得到密文。
- 解密过程:对密文进行逆向操作,包括轮密钥逆序加、逆向列混淆、逆向行移位和逆向字节替代等步骤,最终得到明文。
结果验证:验证解密得到的明文与原始明文是否一致,确保加密和解密的正确性。
加密模式和填充方案
AES算法支持多种加密模式和填充方案,用于满足不同的应用需求。
常见的加密模式包括:
- ECB(Electronic Codebook)模式:将每个分组独立加密,适用于对称性较弱的数据。
- CBC(Cipher Block Chaining)模式:前一个分组的密文与当前分组的明文进行异或操作后再加密,增加了分组之间的关联性。
- CTR(Counter)模式:通过使用计数器生成密钥流,将密钥流与明文进行异或操作得到密文。
常见的填充方案包括:
- PKCS7(Padding Cryptography System 7)填充:在明文末尾添加填充字节,填充字节的值等于需要填充的字节数。
- PKCS5(Padding Cryptography System 5)填充:与PKCS7填充类似,但用于8字节分组的加密算法。
- NoPadding填充:不进行任何填充,要求明文长度必须是分组长度的整数倍。
选择合适的加密模式和填充方案需要考虑数据安全性、效率和系统兼容性等因素。
现加密结果不一致的原因可能是多种多样的。
以下是一些可能导致结果不一致的原因:
- 加密工具使用的是不同的加密算法或加密模式,例如CBC、CFB、OFB等等。
- 加密工具使用的是不同的填充方案,例如PKCS#5、PKCS#7、ISO 10126等等。
- 加密工具对原始数据进行了预处理或后处理,例如添加了Salt或IV。
- 加密工具在进行加密时使用了不同的编码方式,例如Base64、Hex、UTF-8等等。
因此,如果您使用的加密工具和我们在代码中使用的加密方式不同,那么最终的加密结果可能就不同。
总结
AES加密算法是一种高效、安全的对称加密算法,广泛应用于数据保护和网络通信等领域。本文介绍了AES算法的原理、使用步骤以及常见的加密模式和填充方案。了解和掌握AES加密算法对于保护数据的安全和实现机密通信至关重要。
希望本文对您理解AES加密算法有所帮助,如果有任何疑问或需要进一步的信息,请随时提问。
附上对接中国移动互联网加解密的python代码
from base64 import b64encode, encodebytes
import base64
from Crypto.Cipher import AES
import hashlib
key = input['appkey']
mode = AES.MODE_ECB
bs = 16 # block size
#padding= lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
def padding(text):
count = len(text.encode('utf-8'))
add = bs - (count % bs)
entext = text + (chr(add) * add)
return entext
def unpadding(s):
padding_num: int = ord(s[-1])
return s[: -padding_num]
def encrypt(key, text):
md5 = hashlib.md5()
md5.update(key.encode("utf8"))
generator = AES.new(md5.digest(), mode)
crypt = generator.encrypt(padding(text).encode())
crypted_str = base64.b64encode(crypt).decode()
return crypted_str
def decrypt(key,text):
md5 = hashlib.md5()
md5.update(key.encode("utf8"))
generator = AES.new(md5.digest(), mode)
decrpyt_bytes = base64.b64decode(text)
decText= unpadding(generator.decrypt(decrpyt_bytes).decode())
return decText
mobile= encrypt(key,input['mobile'])
name= encrypt(key,input['name'])
idcard= encrypt(key,input['idcard'])
text_decrypted = decrypt(key,mobile)
output={'mobile':mobile,'name':name,'idcard':idcard,text_decrypted:text_decrypted}