本文主要介绍使用AES加密算法的Python实现和shell脚本实现、SM4国密算法的Python实现。Python使用pycryptodome实现AES加解密、使用GmSSL实现SM4加解密算法;Shell脚本使用openssl实现AES加解密,详细见下文。
1)pycryptodome包
pycryptodome是Python中一个常用的加密模块,它是Cryptography及PyCrypto项目的继承者,可以支持多种对称和非对称加密算法,包括AES、Blowfish、RSA和DSA等。在PyCrypto已经不再更新之后,推荐使用pycryptodome来代替PyCrypto。
2)AES加密算法
AES加密算法,全称高级加密标准(Advanced Encryption Standard),是美国联邦政府采用的一种区块加密标准。在密码学中,它是一种对称加密算法,可支持128、192和256位的密钥长度。该算法基于比特块的转换、替换和移位操作,进行多次迭代以实现加密。加密过程中,明文被分成若干个128位的比特块,然后通过与密钥的相互作用,经过多轮加密操作,最终生成密文。每一轮都使用不同的子密钥,而这些子密钥又由原始密钥经过一系列的加密函数生成。
AES加密算法有五种工作模式,这些模式可以应用到数据加密的标准流程中:
AES.MODE_EAX,全称AES Encrypt-and-Authenticate (加密和认证)模式,是一种同时提供加密和认证的密码模式。在这种模式下,即使攻击者能够得到密文和认证数据,没有正确的密钥,他们也无法解密得到明文数据,同时通过认证数据也可以保证数据的完整性。
3)Python实现AES-CBC模式加密和解密
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# 创建AES对象,使用CBC模式,使用一个16字节的随机IV
def aes_encrypt(data, key):
cipher = AES.new(key, AES.MODE_CBC,get_random_bytes(16))
ct_bytes = cipher.encrypt(pad(data, AES.block_size))
iv = cipher.iv
return iv, ct_bytes
# 创建新的AES对象,用于解密
def aes_decrypt(iv, ct_bytes, key):
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
pt = unpad(cipher.decrypt(ct_bytes), AES.block_size)
return pt
# 生成一个随机密钥
key = get_random_bytes(16)
# 加密数据
data = b"Hello@2023"
iv,ct = aes_encrypt(data, key)
print("Ciphertext:", ct)
# 解密数据
decrypted = aes_decrypt(iv, ct, key)
print("Decrypted text:", decrypted)
4)Python实现AES-EAX模式加密和解密
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
#from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# 创建AES对象,使用EAX模式,使用一个16字节的随机IV
def aes_encrypt(data, key):
cipher = AES.new(key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(data)
nonce = cipher.nonce
return ciphertext,tag,nonce
# 创建新的AES对象,用于解密
def aes_decrypt(ct_bytes, key, nonce, tag):
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
pt = cipher.decrypt(ct_bytes)
try:
cipher.verify(tag)
pt_verify = 1
except ValueError:
pt_verify = 0
print('密钥不正确或消息被破坏')
return pt,pt_verify
# 生成一个随机密钥
key = get_random_bytes(16)
# 加密数据
data = b"Hello@2023"
ct,tag,nonce = aes_encrypt(data, key)
print("Ciphertext:", ct)
# 解密数据
decrypted,flag = aes_decrypt(ct, key, nonce, tag)
if flag==1:
print("Decrypted text:", decrypted)
else:
print('密钥不正确或消息被破坏')
1)GmSSL库
GmSSL是由北京大学自主开发的国产商用密码开源库,实现了对国密算法、标准和安全通信协议的全面功能覆盖,包括SM3、SM4等国密算法。该库支持包括移动端在内的主流操作系统和处理器,支持密码钥匙、密码卡等典型国产密码硬件,并提供了功能丰富的命令行工具以及多种编译语言编程接口。此外,GmSSL大幅度降低了内存需求和二进制代码体积,具有轻量化的特点。
2)SM1、SM2、SM3和SM4加密算法
SM1、SM2、SM3和SM4是中国国家密码管理局发布的四个密码算法标准,介绍如下:
3)Python实现SM4算法加密和解密
# -*- coding: utf-8 -*-
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import binascii
import os
def str_to_hexStr(hex_str):
"""
字符串转hex
:param hex_str: 字符串
:return: hex
"""
hex_data = hex_str.encode('utf-8')
str_bin = binascii.unhexlify(hex_data)
return str_bin.decode('utf-8')
def encrypt(crypt_sm4,encrypt_key, value):
"""
国密sm4加密
:param encrypt_key: sm4加密key
:param value: 待加密的字符串
:return: sm4加密后的hex值
"""
crypt_sm4.set_key(encrypt_key, SM4_ENCRYPT)
encrypt_value = crypt_sm4.crypt_ecb(value) # bytes类型
return encrypt_value.hex()
def decrypt(crypt_sm4,decrypt_key, encrypt_value):
"""
国密sm4解密
:param decrypt_key:sm4加密key
:param encrypt_value: 待解密的hex值
:return: 原字符串
"""
crypt_sm4.set_key(decrypt_key, SM4_DECRYPT)
decrypt_value = crypt_sm4.crypt_ecb(bytes.fromhex(encrypt_value)) # bytes类型
return str_to_hexStr(decrypt_value.hex())
key = os.urandom(16)
value = b'Hello@2023' # bytes类型
crypt_sm4 = CryptSM4()
# 加密
enc_value = encrypt(crypt_sm4,key,value)
#解密
dec_value = encrypt(crypt_sm4,key,enc_value)
在Shell脚本中,可以使用OpenSSL命令行工具来实现AES解密。
完整代码如下所示:
#!/bin/bash
# 加密/解密工具
program_openssl=$(command -v openssl)
program_gpg=$(command -v gpg)
# 待加密/解密的数据
data_file="data.txt"
# 加密后的数据文件
encrypted_file="encrypted.aes"
# 解密后的数据文件
decrypted_file="decrypted.txt"
# 密钥(16字节)
key=$(cat /dev/urandom |head -n 16|md5sum |cut -c 1-16)
# 初始化向量(16字节)
iv=$(cat /dev/urandom |head -n 16|md5sum |cut -c 1-16)
# 使用AES-256加密
function encrypt() {
if [ -f "$data_file" ]; then
if [ -x "$program_openssl" ]; then
openssl enc -nosalt -K "$key" -iv "$iv" -in "$data_file" -out "$encrypted_file" -aes-256-cbc
if [ $? -eq 0 ]; then
echo "加密成功!加密后的数据在 $encrypted_file 文件中。"
else
echo "加密失败。"
fi
else
echo "未找到 openssl 命令。"
fi
else
echo "未找到待加密的数据文件 $data_file。"
fi
}
# 使用AES-256解密
function decrypt() {
if [ -f "$encrypted_file" ]; then
if [ -x "$program_openssl" ]; then
openssl enc -d -nosalt -K "$key" -iv "$iv" -in "$encrypted_file" -out "$decrypted_file" -aes-256-cbc
if [ $? -eq 0 ]; then
echo "解密成功!解密后的数据在 $decrypted_file 文件中。"
else
echo "解密失败。"
fi
else
echo "未找到 openssl 命令。"
fi
else
echo "未找到待解密的数据文件 $encrypted_file。"
fi
}
# 测试AES加密和解密
encrypt
decrypt
参考资料: