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/