当前位置: 首页 > 工具软件 > gmssl-python > 使用案例 >

使用 python gmssl 完成SM4

杜浩壤
2023-12-01

1.1语言:python
1.2库:gmssl
2、过程
2.1 密钥生成
使用func.list_to_bytes函数编写随机密钥生成函数key_gen(无输入,输出bytes类型的随机SM4密钥),需要注意密钥的位数
2.2 iv生成
使用func.list_to_bytes函数编写随机iv生成函数iv_gen(无输入,输出bytes类型的随机SM4 iv),需要注意iv的位数
2.3 SM4_ecb
(1)编写SM4_ecb模式的加密函数SM4_ecb_enc(输入明文和密钥,输出密文,输入和输出均为bytes类型)
(2)编写SM4_ecb模式的解密函数SM4_ecb_dec(输入密文和密钥,输出明文,输入和输出均为bytes类型)
2.4 SM4_cbc
(1)编写SM4_cbc模式的加密函数SM4_cbc_enc(输入明文、iv和密钥,输出密文,输入和输出均为bytes类型)
(2)编写SM4_cbc模式的解密函数SM4_cbc_dec(输入密文、iv和密钥,输出明文,输入和输出均为bytes类型)
2.5 字符串加密
编写exp_SM4_str函数,输入为明文(str类型),无输出,具体过程:
(1)调用key_gen函数,打印生成的随机密钥
(2)调用SM4_ecb_enc函数将明文加密,打印加密后的密文
(3)调用SM4_ecb_dec函数将密文解密,打印解密后的明文
(4)调用key_gen函数,打印生成的随机密钥
(5)调用iv_gen函数,打印生成的随机iv
(6)调用SM4_cbc_enc函数将明文加密,打印加密后的密文
(7)调用SM4_cbc_dec函数将密文解密,打印解密后的明文
2.6 文件加密
编写exp_SM4_file函数,输入为文件地址(str类型),无输出,具体过程:
(1)调用key_gen函数,打印生成的随机密钥
(2)调用open函数打开并读取输入的文件(bytes类型)
(3)调用SM4_ecb_enc函数将文件内容加密,将密文保存到项目目录中,密文文件名为《file_enc_ecb.txt》,打印相关信息
(4)调用open函数打开并读取上一步中生成的加密文件
(5)调用SM4_ecb_dec函数将文件内容解密,将明文保存到项目目录中,明文文件名为《file_dec_ecb.txt》,打印相关信息
(6)调用密钥生成函数,打印生成的随机密钥
(7)调用iv生成函数,打印生成的随机iv
(8)调用SM4_cbc_enc函数将输入的文件加密,将密文保存到项目目录中,密文文件名为《file_enc_cbc.txt》,打印相关信息
(9)调用file函数打开并读取上一步中生成的加密文件
(10)调用SM4_cbc_dec函数将文件内容解密,将明文保存到项目目录中,明文文件名为《file_dec_cbc.txt》,打印相关信息
2.7 main函数
在main函数中,使用input函数获取用户的输入。
(1)如果用户输入“file”,则调用exp_SM4_file函数,输入为文件路径(可以固定为项目目录下的plaintext.txt文件即“.\plaintext.txt”,也可以自定义路径),示例结果如下:


import random
#from gmssl import func
import string
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT

crypt_sm4 = CryptSM4()


def gen_key(bits):
    #key = random.randbytes(15)
    #key = random.sample('zyxwvutsrqponmlkjihgfedcba1234567890', 5)
    num_set = [chr(i) for i in range(48, 58)]
    char_set = [chr(i) for i in range(97, 123)]
    total_set = num_set + char_set
    key = "".join(random.sample(total_set, bits))
    #key = ''.join(random.sample(string.ascii_letters + string.digits, 15))
    return key





def iv_gen(bits):
    num_set = [chr(i) for i in range(48, 58)]
    char_set = [chr(i) for i in range(97, 123)]
    total_set = num_set + char_set
    iv = "".join(random.sample(total_set, bits))
    #iv = ''.join(random.sample(string.ascii_letters + string.digits, 15))
    return iv





def SM4_ecb_enc(plaintext, key):
    crypt_sm4.set_key(key, SM4_ENCRYPT)
    ciphertext_bytes = crypt_sm4.crypt_ecb(plaintext)
    
    return ciphertext_bytes




def SM4_ecb_dec(ciphertext, key):
    crypt_sm4 = CryptSM4()
    crypt_sm4.set_key(key, SM4_DECRYPT)
    plaintext_bytes = crypt_sm4.crypt_ecb(ciphertext)
   
    return plaintext_bytes




def SM4_cbc_enc(plaintext, iv, key):
    crypt_sm4.set_key(key, SM4_ENCRYPT)
    ciphertext_bytes= crypt_sm4.crypt_cbc(iv, plaintext)  # bytes类型
    
    return ciphertext_bytes



def SM4_cbc_dec(ciphertext,iv,key):
    crypt_sm4.set_key(key, SM4_DECRYPT)
    plaintext_bytes = crypt_sm4.crypt_cbc(iv, ciphertext)
    
    return plaintext_bytes





def exp_SM4_str(plaintext):
    plaintext_bytes = bytes(plaintext, encoding="utf8")
    return plaintext_bytes

def exp_SM4_file(filename):
    with open(filename, "rb") as f:
         plaintext_bytes = f.read()
    f.close()
    return plaintext_bytes


if __name__ == '__main__':
    
    key = gen_key(16)
    key_bytes = bytes(key, encoding="utf8")
    with open('D:/key_bytes.txt','wb') as f:
        f.truncate()
        f.write(key_bytes)
    f.close
    print("key为:", key_bytes.hex())

    iv = iv_gen(16)
    iv_bytes = bytes(iv, encoding="utf8")
    with open('D:/iv_bytes.txt','wb') as f:
        f.truncate()
        f.write(iv_bytes)
    f.close
    print("iv为:", iv_bytes.hex())
    
    choice=input("选择字符串加密还是文件加密")
    if (choice == 'file'):
        print ("请输入需要加密的文件名:")
        plaintext_bytes = exp_SM4_file(input())
    
    else:
       print("请输入需要加密的内容:")
       plaintext_bytes = exp_SM4_str(input())

    ciphertext = SM4_ecb_enc(plaintext_bytes, key_bytes)
    with open('D:/ciphertext_ecb.txt','wb') as f:
        f.truncate()
        f.write(ciphertext)
    f.close
    print("ecb加密为:", ciphertext)

    plaintext = SM4_ecb_dec(ciphertext, key_bytes)
    with open('D:/plaintext_ecb.txt','wb') as f:
        f.truncate()
        f.write(plaintext)
    f.close
    print("ecb解密为:", plaintext)

    ciphertext = SM4_cbc_enc(plaintext, iv_bytes, key_bytes)
    with open('D:/ciphertext_cbc.txt','wb') as f:
        f.truncate()
        f.write(ciphertext)
    f.close
    print("cbc加密为:", ciphertext)

    plaintext = SM4_cbc_dec(ciphertext, iv_bytes, key_bytes)
    with open('D:/plaintext_cbc.txt','wb') as f:
        f.truncate()
        f.write(plaintext)
    f.close
    print("cbc解密为:", plaintext)

Gmssl python参考资料:https://gitee.com/mirrors/gmssl-python
Gmssl参考资料:http://gmssl.org/

 类似资料: