Python实现AES算法和国密SM4算法

本文主要介绍使用AES加密算法的Python实现和shell脚本实现、SM4国密算法的Python实现。Python使用pycryptodome实现AES加解密、使用GmSSL实现SM4加解密算法;Shell脚本使用openssl实现AES加解密,详细见下文。


1、Python实现加密和解密
1.1 Python实现AES加密和解密

1)pycryptodome包

pycryptodome是Python中一个常用的加密模块,它是Cryptography及PyCrypto项目的继承者,可以支持多种对称和非对称加密算法,包括AES、Blowfish、RSA和DSA等。在PyCrypto已经不再更新之后,推荐使用pycryptodome来代替PyCrypto。

Python实现AES算法和国密SM4算法_第1张图片

2)AES加密算法

AES加密算法,全称高级加密标准(Advanced Encryption Standard),是美国联邦政府采用的一种区块加密标准。在密码学中,它是一种对称加密算法,可支持128、192和256位的密钥长度。该算法基于比特块的转换、替换和移位操作,进行多次迭代以实现加密。加密过程中,明文被分成若干个128位的比特块,然后通过与密钥的相互作用,经过多轮加密操作,最终生成密文。每一轮都使用不同的子密钥,而这些子密钥又由原始密钥经过一系列的加密函数生成。

AES加密算法有五种工作模式,这些模式可以应用到数据加密的标准流程中:

  • 电码本模式(Electronic Codebook (ECB)):将整个明文分成若干段相同的小段,然后对每一小段进行加密。
  • 密码分组链接模式(Cipher Block Chaining (CBC)):先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
  • 计算器模式(Counter (CTR)):不常见,使用一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。
  • 密码反馈模式(Cipher FeedBack (CFB)):比较复杂,IV(初始化向量)将加密后的密文length-n位再次加密,每次能加密n位。
  • 输出反馈模式(Output FeedBack (OFB)):比较复杂。

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.2 Python实现国密SM4加密和解密

1)GmSSL库

GmSSL是由北京大学自主开发的国产商用密码开源库,实现了对国密算法、标准和安全通信协议的全面功能覆盖,包括SM3、SM4等国密算法。该库支持包括移动端在内的主流操作系统和处理器,支持密码钥匙、密码卡等典型国产密码硬件,并提供了功能丰富的命令行工具以及多种编译语言编程接口。此外,GmSSL大幅度降低了内存需求和二进制代码体积,具有轻量化的特点。

Python实现AES算法和国密SM4算法_第2张图片

2)SM1、SM2、SM3和SM4加密算法

SM1、SM2、SM3和SM4是中国国家密码管理局发布的四个密码算法标准,介绍如下:

  • SM1是一种对称密码算法。它的密钥长度为128位,分组长度为128位,采用分组密码的加密方式,即将明文分为若干个长度相同的分组,每个分组进行加密运算,最后合并为密文。SM1的加密过程中包括了置换、代换、线性变换等步骤,从而保证了加密的强度和安全性。需要注意的是,SM1算法仅用于加密小数据量。
  • SM2是一种非对称密码算法。它采用了椭圆曲线密码学,可以用于数字签名、密钥协商、加密和解密等操作。SM2的安全性基于离散对数问题的难度,通过椭圆曲线的运算实现加密和解密操作。它的私钥长度为256位,公钥长度为512位,可以提供与1024位RSA算法相当的安全性。
  • SM3是一种哈希函数。它可以用于对任意长度的消息进行摘要操作,可以生成一个固定长度的消息摘要。SM3算法采用了置换、代换、移位、加法等操作,可以保证摘要的强度和唯一性。它的安全性可达到256位。
  • SM4是一种分组对称密码算法。它的密钥长度为128位,分组长度为128位,具有高效性和安全性。SM4算法采用了Feistel结构,将明文分成多个数据块,每个数据块分别进行加密操作。SM4算法采用了S盒、置换、线性变换等操作,从而保证了加密的强度和安全性。

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)
2、Shell脚本实现AES加密和解密

在Shell脚本中,可以使用OpenSSL命令行工具来实现AES解密。

  • 使用urandom生成16字节的随机字符串
  • 使用openssl enc -aes-256-cbc实现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

参考资料:

  1. https://pypi.org/project/gmssl/

你可能感兴趣的:(python,python,算法)