• 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。

    在这里插入图片描述

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    1.2 Python实现国密SM4加密和解密

    1)GmSSL库

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

    在这里插入图片描述

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    参考资料:

    1. https://pypi.org/project/gmssl/
  • 相关阅读:
    有没有看下concat函数这个符号报错问题?应该是网站自己的问题?
    项目一共30个模块,你叫我maven版本一个个手动改?
    CISSP通关学习笔记:共计 9 个章节(已完结)
    工作学习记录
    2022-09-09 mysql列存储引擎-tianmu_ini_allowmysqlquerypath参数开启后的异常记录
    .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
    实现数组去重的七种方法
    化合物在高通量筛选中的作用
    一款好看的博客园主题皮肤-Rebuild From Silence Theme
    使用node-cmd重启electron
  • 原文地址:https://blog.csdn.net/solihawk/article/details/133651566