From 658c939613b23b3a93eb11709d2446374f681666 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 14:28:29 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E5=AE=8C=E6=88=90RSA=E3=80=81=E5=AE=8C?= =?UTF-8?q?=E6=88=90SM4=E3=80=81=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=8E=A5=E6=94=B6=E8=80=85=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 ++++ config/config.py | 25 +++++++++++++- recv/recv.py | 44 ++++++++++++++++++++++++- recv/test_recv.py | 8 +++++ tool/PriKeyHelper.py | 28 +++++++++++++--- tool/asymmetric/RSA.py | 68 +++++++++++++++++++++++++++++++++++++++ tool/symmetric/SM4.py | 67 ++++++++++++++++++++++++++++++++++++++ tool/test_PriKeyHelper.py | 39 ++++++++++++++++++++++ 8 files changed, 279 insertions(+), 6 deletions(-) create mode 100644 recv/test_recv.py create mode 100644 tool/test_PriKeyHelper.py diff --git a/.gitignore b/.gitignore index a09c56d..56c7dcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,7 @@ /.idea +/tool/asymmetric/private.pem +/tool/asymmetric/public.pem +/tool/public.pem +/tool/private.pem +/private.pem +/public.pem diff --git a/config/config.py b/config/config.py index fb63607..6804a94 100644 --- a/config/config.py +++ b/config/config.py @@ -1,2 +1,25 @@ +from enum import Enum, auto port = 8426 -priKeySavePath = "./priKey.txt" \ No newline at end of file +priKeySavePath = "./private.pem" +pubKeySavePath = "./public.pem" + +class EncryptType(Enum): + AES_ECB = auto() + AES_CBC = auto() + AES_CFB = auto() + AES_OFB = auto() + SM4_ECB = auto() + SM4_CBC = auto() + +# 函数:通过文本获取枚举成员 +def getEncryptType(text): + try: + return EncryptType[text] + except KeyError: + raise ValueError(f"Invalid EncryptType name: {text}") + +# 函数:通过枚举成员获取文本 +def getEncryptTypeName(encryptType): + if not isinstance(encryptType, EncryptType): + raise TypeError("Expected a EncryptType enum member") + return encryptType.name \ No newline at end of file diff --git a/recv/recv.py b/recv/recv.py index d0c8c31..a215b8f 100644 --- a/recv/recv.py +++ b/recv/recv.py @@ -1,4 +1,11 @@ +import base64 + +from config import config from entity.Letter import Letter +from tool import PriKeyHelper +from tool.asymmetric import RSA +from tool.symmetric import SM4 + def getLetter(): # 阻塞自身 从指定端口获取信件 @@ -9,4 +16,39 @@ def getLetter(): pass def handleLetter(letter:Letter): - pass \ No newline at end of file + # 解析信件 确认收信人 + # 获取自身key + pki = PriKeyHelper.getUserKey() + if pki[1] != letter.recvPubKey: + raise Exception("信件不属于自己") + # 用自己的私钥解密key 获得对称加密秘钥。 + key = RSA.decrypt_message(letter.encryptKey,pki[0]) + + # 根据不同的对称加密算法 + try: + type = config.getEncryptType(letter.encryptType) + except KeyError: + raise KeyError("不支持的对称加密算法") + # 进行解密fileBase64 + data = None + if type == config.EncryptType.SM4_ECB: + SM4.decrypt_ecb(base64.b64decode(letter.fileBase64),key) + elif type == config.EncryptType.SM4_CBC: + SM4.decrypt_cbc_with_iv(base64.b64decode(letter.fileBase64),key) + elif type == config.EncryptType.AES_GCM: + raise NotImplementedError("未实现") + elif type == config.EncryptType.AES_CBC: + raise NotImplementedError("未实现") + else: + raise KeyError("不支持的对称加密算法") + + # 用发信人的公钥验签摘要 + result = RSA.verify_signature(data,letter.sign,letter.senderPubKey) + if not result: + raise Exception("签名验证失败,文件不可信") + + # 保存文件 + with open(f"./{letter.fileName}","wb") as f: + f.write(data) + + return \ No newline at end of file diff --git a/recv/test_recv.py b/recv/test_recv.py new file mode 100644 index 0000000..26601b1 --- /dev/null +++ b/recv/test_recv.py @@ -0,0 +1,8 @@ +from sender import sender +from tool import PriKeyHelper + + +def test_handleLetter(): + pki = PriKeyHelper.getUserKey() + + pass \ No newline at end of file diff --git a/tool/PriKeyHelper.py b/tool/PriKeyHelper.py index 23feb16..63b12d3 100644 --- a/tool/PriKeyHelper.py +++ b/tool/PriKeyHelper.py @@ -1,4 +1,24 @@ -def getUserKey() -> (str, str): - # 获取用户的公私钥对,若不存在,则生成之 - # 返回 私钥,公钥 格式 - pass +import base64 +import os + +from config import config +from tool.asymmetric import RSA + + +def getUserKey() -> (str, str): # 返回base64编码 + # 检查是否存在公私钥文件 + if not os.path.exists(config.priKeySavePath) or not os.path.exists(config.pubKeySavePath): + # 生成新的密钥对 + RSA.generate_keys(config.priKeySavePath,config.pubKeySavePath) + + # 读取私钥 + with open(config.priKeySavePath, "rb") as f: + data = f.read() + private_key = base64.b64encode(data).decode('utf-8') + + # 读取公钥 + with open(config.pubKeySavePath, "rb") as f: + data = f.read() + public_key = base64.b64encode(data).decode('utf-8') + + return private_key, public_key diff --git a/tool/asymmetric/RSA.py b/tool/asymmetric/RSA.py index e69de29..652e4f5 100644 --- a/tool/asymmetric/RSA.py +++ b/tool/asymmetric/RSA.py @@ -0,0 +1,68 @@ +import base64 +import binascii +from Crypto.Cipher import PKCS1_OAEP +from Crypto.PublicKey import RSA +from Crypto.Signature import pkcs1_15 +from Crypto.Hash import SHA256 + + +def generate_keys(priKeySavePath, pubKeySavePath): + # 生成一个RSA密钥对象 + key = RSA.generate(2048) + + # 导出私钥 + private_key = key.export_key() + with open(priKeySavePath, "wb") as f: + f.write(private_key) + + # 导出公钥 + public_key = key.publickey().export_key() + with open(pubKeySavePath, "wb") as f: + f.write(public_key) + + +def encrypt_message(message, public_key_base64): + # 加载公钥 + public_key_bin = base64.b64decode(public_key_base64) + public_key = RSA.import_key(public_key_bin) + # 使用公钥加密消息 + cipher_rsa = PKCS1_OAEP.new(public_key) + encrypted_message = cipher_rsa.encrypt(message.encode('utf-8')) + + return binascii.hexlify(encrypted_message).decode('utf-8') + + +def decrypt_message(encrypted_message, private_key_base64): + # 加载私钥 + private_key_bin = base64.b64decode(private_key_base64) + private_key = RSA.import_key(private_key_bin) + # 使用私钥解密消息 + cipher_rsa = PKCS1_OAEP.new(private_key) + decrypted_message = cipher_rsa.decrypt(binascii.unhexlify(encrypted_message)) + + return decrypted_message.decode('utf-8') + +def sign_message(message, private_key_base64): + # 加载私钥 + private_key_bin = base64.b64decode(private_key_base64) + private_key = RSA.import_key(private_key_bin) + # 计算消息的哈希值 + hash_obj = SHA256.new(message.encode('utf-8')) + # 使用私钥对哈希值进行签名 + signature = pkcs1_15.new(private_key).sign(hash_obj) + + return binascii.hexlify(signature).decode('utf-8') + + +def verify_signature(message, signature, public_key_base64): + # 加载公钥 + public_key_bin = base64.b64decode(public_key_base64) + public_key = RSA.import_key(public_key_bin) + # 计算消息的哈希值 + hash_obj = SHA256.new(message.encode('utf-8')) + # 使用公钥验证签名 + try: + pkcs1_15.new(public_key).verify(hash_obj, binascii.unhexlify(signature)) + return True + except (ValueError, TypeError): + return False diff --git a/tool/symmetric/SM4.py b/tool/symmetric/SM4.py index e69de29..d3d53e1 100644 --- a/tool/symmetric/SM4.py +++ b/tool/symmetric/SM4.py @@ -0,0 +1,67 @@ +import os + +from gmssl import sm4 + +def encrypt_ecb(data, key): + cipher = sm4.CryptSM4() + cipher.set_key(key.encode('utf-8'), sm4.SM4_ENCRYPT) + encrypted_data = cipher.crypt_ecb(data.encode('utf-8')) + return encrypted_data.hex() + +def decrypt_ecb(encrypted_hex, key): + cipher = sm4.CryptSM4() + cipher.set_key(key.encode('utf-8'), sm4.SM4_DECRYPT) + decrypted_data = cipher.crypt_ecb(bytes.fromhex(encrypted_hex)) + return decrypted_data.decode('utf-8') + +def encrypt_cbc_with_iv(data, key): + cipher = sm4.CryptSM4() + cipher.set_key(key.encode('utf-8'), sm4.SM4_ENCRYPT) + + # 生成随机的16字节IV + iv = os.urandom(16) + + # 加密数据 + encrypted_data = cipher.crypt_cbc(iv, data.encode('utf-8')) + + # 将IV和加密后的数据拼接在一起 + return iv + encrypted_data + +def decrypt_cbc_with_iv(encrypted_bytes, key): + cipher = sm4.CryptSM4() + cipher.set_key(key.encode('utf-8'), sm4.SM4_DECRYPT) + + # 提取IV + iv = encrypted_bytes[:16] + + # 提取加密后的数据 + encrypted_data = encrypted_bytes[16:] + + # 解密数据 + decrypted_data = cipher.crypt_cbc(iv, encrypted_data) + return decrypted_data.decode('utf-8') + +if __name__ == "__main__": + # 示例数据和密钥 + data = "Hello, SM4!" + key = "1234567890abcdef" + + # 加密 + encrypted_data = encrypt_ecb(data, key) + print(f"Encrypted: {encrypted_data}") + + # 解密 + decrypted_data = decrypt_ecb(encrypted_data, key) + print(f"Decrypted: {decrypted_data}") + + # 示例数据和密钥 + data = "Hello, SM4 CBC with random IV!" + key = "1234567890abcdef" + + # 加密 + encrypted_data = encrypt_cbc_with_iv(data, key) + print(f"Encrypted: {encrypted_data.hex()}") + + # 解密 + decrypted_data = decrypt_cbc_with_iv(encrypted_data, key) + print(f"Decrypted: {decrypted_data}") diff --git a/tool/test_PriKeyHelper.py b/tool/test_PriKeyHelper.py new file mode 100644 index 0000000..8de5054 --- /dev/null +++ b/tool/test_PriKeyHelper.py @@ -0,0 +1,39 @@ +import pytest + +from tool import PriKeyHelper +from tool.asymmetric import RSA + + +def test_encrypt(): + key = PriKeyHelper.getUserKey() + message = "Hello, this is a secret message." + # 打印keys + print(key[0]) + print(key[1]) + + # 加密消息 + encrypted = RSA.encrypt_message(message, key[1]) + print(f"Encrypted: {encrypted}") + + # 解密消息 + decrypted = RSA.decrypt_message(encrypted, key[0]) + print(f"Decrypted: {decrypted}") + + +def test_sign(): + + key = PriKeyHelper.getUserKey() + message = "This is a signed message." + # 打印keys + print(key[0]) + print(key[1]) + + + # 签名消息 + signature = RSA.sign_message(message, key[0]) + print(f"Signature: {signature}") + + # 验证签名 + is_valid = RSA.verify_signature(message, signature, key[1]) + print(f"Is Signature Valid? {is_valid}") + assert is_valid == True \ No newline at end of file From ceb244792b9dd0f6d43166a681753e71a624e338 Mon Sep 17 00:00:00 2001 From: UniDarkstars <1830018670@qq.com> Date: Sun, 24 Nov 2024 14:31:55 +0800 Subject: [PATCH 02/12] =?UTF-8?q?aes=E6=96=87=E4=BB=B6=EF=BC=8Csender?= =?UTF-8?q?=E5=8A=A0=E5=AF=86=E6=96=B9=E6=B3=95=E5=92=8C=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sender/sender.py | 53 +++++++++++++++++++++++++++++++++++++++++++ tool/symmetric/AES.py | 35 ++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/sender/sender.py b/sender/sender.py index 30aad6c..0535295 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,4 +1,7 @@ +# 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 from entity.Letter import Letter +from tool.symmetric.AES import AESUtils + def main(): # 用户输入各种数据填充letter字段 @@ -6,6 +9,56 @@ def main(): # 使用对方的公钥进行加密 # 发送信件 pass + + def sendLetter(letter: Letter, target="192.168.195.162:8426"): # 向目标ip和端口发送指定的信件 pass + +# 选择对称加密的方法和模式(aes/sm2) +def selectSymEncryptionChoice(): + encryWay = "" + encryMode = "" + + # 选择加密算法 + while True: + encryWay = input("Choose the way for encryption (aes/sm2): ").strip().lower() # 统一转成小写 + if encryWay in ["aes", "sm2"]: + print(f"You have selected '{encryWay}' encryption.") + break # 输入有效后退出循环 + else: + print("Invalid choice. Please enter 'aes' or 'sm2'.") + + # 选择加密算法的模式 + while True: + if encryWay == "aes": + encryMode = input("Choose the encryption mode (ecb/cbc/cfb/ofb): ").strip().lower() + if encryMode in ["ecb", "cbc", "cfb", "ofb"]: + print(f"You have selected '{encryMode}' encryption mode.") + break # 输入有效后退出循环 + else: + print("Invalid choice. Please enter ecb/cbc/cfb/ofb") + + elif encryWay == "sm2": + print() + break # 输入有效后退出循环 + + return encryWay, encryMode + + +# 使用对称加密,返回加密后的数据和随机生成的密钥 +def SymEncryption(): + + # 获得加密的方法和加密的模式 + way, mode = selectSymEncryptionChoice() + + if way == "aes": + aesUtils = AESUtils() + encryptedData, key = aesUtils.encrypt("test", mode=mode) # 这里data要改为文件内容 + return encryptedData + + if way == "sm2": + pass + +def getKey(): + pass diff --git a/tool/symmetric/AES.py b/tool/symmetric/AES.py index e69de29..034e7ff 100644 --- a/tool/symmetric/AES.py +++ b/tool/symmetric/AES.py @@ -0,0 +1,35 @@ +# "ecb", "cbc", "cfb", "ofb" + +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad +from Crypto.Random import get_random_bytes +import base64 + +class AESUtils: + def __init__(self, key: bytes = None): + """初始化 AES 加密工具,如果没有提供密钥,则生成一个随机密钥""" + if key is None: + self.key = get_random_bytes(32) # AES-256 + else: + self.key = key + + def encrypt(self, data: str, mode: str = 'ECB') -> str: + """加密数据""" + cipher = self._get_cipher(mode) + data = pad(data.encode(), AES.block_size) # 填充数据 + ciphertext = cipher.encrypt(data) + return base64.b64encode(ciphertext).decode() + + def _get_cipher(self, mode: str) -> AES: + """根据模式返回相应的 AES cipher""" + iv = None + if mode == 'CBC': + iv = get_random_bytes(AES.block_size) + return AES.new(self.key, AES.MODE_CBC, iv), self.key + elif mode == 'CFB': + return AES.new(self.key, AES.MODE_CFB), self.key + elif mode == 'OFB': + return AES.new(self.key, AES.MODE_OFB), self.key + else: # 默认是 ECB + return AES.new(self.key, AES.MODE_ECB), self.key + From c349bc3039027998368f20d2b210230469f13960 Mon Sep 17 00:00:00 2001 From: UniDarkstars <1830018670@qq.com> Date: Sun, 24 Nov 2024 14:49:39 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E4=BD=AC=E6=9D=A5=E5=B8=AE=E6=88=91=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E4=B8=80=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sender/sender.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sender/sender.py b/sender/sender.py index 0535295..2831a8e 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -15,6 +15,7 @@ def sendLetter(letter: Letter, target="192.168.195.162:8426"): # 向目标ip和端口发送指定的信件 pass + # 选择对称加密的方法和模式(aes/sm2) def selectSymEncryptionChoice(): encryWay = "" @@ -47,18 +48,27 @@ def selectSymEncryptionChoice(): # 使用对称加密,返回加密后的数据和随机生成的密钥 -def SymEncryption(): - +def SymEncryption(encryData, key: bytes = None): # 获得加密的方法和加密的模式 way, mode = selectSymEncryptionChoice() if way == "aes": - aesUtils = AESUtils() - encryptedData, key = aesUtils.encrypt("test", mode=mode) # 这里data要改为文件内容 + aesUtils = AESUtils(key) + # tureKey 为 真实返回的Key,如果没有设置初始值,那么key是随机生成 + encryptedData, tureKey = aesUtils.encrypt(encryData, mode=mode) # 这里encryData要改为文件内容 return encryptedData if way == "sm2": pass + def getKey(): pass + + +if __name__ == "__main__": + # 示例数据和密钥 + data = "Hello, AES!" + key = "1234567890abcdef" + + SymEncryption(data) From 685bccaa93724899c800772abdae9e19553aa52b Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 15:03:51 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86bug?= =?UTF-8?q?=EF=BC=8C=E5=B8=B8=E8=A7=84=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- recv/recv.py | 2 +- sender/sender.py | 9 ++++++--- tool/symmetric/AES.py | 12 ++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/recv/recv.py b/recv/recv.py index a215b8f..ac101ff 100644 --- a/recv/recv.py +++ b/recv/recv.py @@ -35,7 +35,7 @@ def handleLetter(letter:Letter): SM4.decrypt_ecb(base64.b64decode(letter.fileBase64),key) elif type == config.EncryptType.SM4_CBC: SM4.decrypt_cbc_with_iv(base64.b64decode(letter.fileBase64),key) - elif type == config.EncryptType.AES_GCM: + elif type == config.EncryptType.AES_ECB: raise NotImplementedError("未实现") elif type == config.EncryptType.AES_CBC: raise NotImplementedError("未实现") diff --git a/sender/sender.py b/sender/sender.py index 2831a8e..cddad9e 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -56,7 +56,7 @@ def SymEncryption(encryData, key: bytes = None): aesUtils = AESUtils(key) # tureKey 为 真实返回的Key,如果没有设置初始值,那么key是随机生成 encryptedData, tureKey = aesUtils.encrypt(encryData, mode=mode) # 这里encryData要改为文件内容 - return encryptedData + return encryptedData,tureKey if way == "sm2": pass @@ -69,6 +69,9 @@ def getKey(): if __name__ == "__main__": # 示例数据和密钥 data = "Hello, AES!" - key = "1234567890abcdef" + # key = "1234567890abcdef" + print(data) - SymEncryption(data) + data,key = SymEncryption(data) + + print(data,key) \ No newline at end of file diff --git a/tool/symmetric/AES.py b/tool/symmetric/AES.py index 034e7ff..a13d576 100644 --- a/tool/symmetric/AES.py +++ b/tool/symmetric/AES.py @@ -13,23 +13,23 @@ class AESUtils: else: self.key = key - def encrypt(self, data: str, mode: str = 'ECB') -> str: + def encrypt(self, data: str, mode: str = 'ECB') -> (str,str): """加密数据""" cipher = self._get_cipher(mode) data = pad(data.encode(), AES.block_size) # 填充数据 ciphertext = cipher.encrypt(data) - return base64.b64encode(ciphertext).decode() + return base64.b64encode(ciphertext).decode(),self.key def _get_cipher(self, mode: str) -> AES: """根据模式返回相应的 AES cipher""" iv = None if mode == 'CBC': iv = get_random_bytes(AES.block_size) - return AES.new(self.key, AES.MODE_CBC, iv), self.key + return AES.new(self.key, AES.MODE_CBC, iv) elif mode == 'CFB': - return AES.new(self.key, AES.MODE_CFB), self.key + return AES.new(self.key, AES.MODE_CFB) elif mode == 'OFB': - return AES.new(self.key, AES.MODE_OFB), self.key + return AES.new(self.key, AES.MODE_OFB) else: # 默认是 ECB - return AES.new(self.key, AES.MODE_ECB), self.key + return AES.new(self.key, AES.MODE_ECB) From b3a21d30cdcd5788f178da9acbf96741f122ab67 Mon Sep 17 00:00:00 2001 From: UniDarkstars <1830018670@qq.com> Date: Sun, 24 Nov 2024 16:21:00 +0800 Subject: [PATCH 05/12] =?UTF-8?q?sender=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E5=8A=A0=E5=AF=86=EF=BC=8C=E5=B9=B6=E4=B8=94=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E4=BC=98=E5=8C=96=E4=BA=86=E8=BE=93=E5=87=BA=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=92=8C=E4=BB=A3=E7=A0=81=EF=BC=8Cletter=E5=B0=B1?= =?UTF-8?q?=E6=94=B9=E4=BA=86=E4=B8=80=E4=B8=8B=E6=A0=BC=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?AES=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/Letter.py | 2 +- sender/sender.py | 51 +++++++++++++++++++++++++++++-------------- tool/symmetric/AES.py | 27 ++++++++++++++++++----- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/entity/Letter.py b/entity/Letter.py index e5b4113..829ac54 100644 --- a/entity/Letter.py +++ b/entity/Letter.py @@ -1,6 +1,6 @@ class Letter: sign = "计算得到" - encryptType = "SM4-GCM" + encryptType = "SM4_GCM" encryptKey = "计算获得" recvPubKey = "" senderPubKey = "" diff --git a/sender/sender.py b/sender/sender.py index cddad9e..9915251 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,7 +1,12 @@ # 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 from entity.Letter import Letter from tool.symmetric.AES import AESUtils +from tool.symmetric.SM4 import encrypt_ecb, decrypt_cbc_with_iv +from Crypto.Random import get_random_bytes +# 两个变量,记录信封 +letterWay = "" +letterMode = "" def main(): # 用户输入各种数据填充letter字段 @@ -16,33 +21,40 @@ def sendLetter(letter: Letter, target="192.168.195.162:8426"): pass -# 选择对称加密的方法和模式(aes/sm2) +# 选择对称加密的方法和模式(aes/sm4) def selectSymEncryptionChoice(): + global letterWay, letterMode encryWay = "" encryMode = "" # 选择加密算法 while True: - encryWay = input("Choose the way for encryption (aes/sm2): ").strip().lower() # 统一转成小写 - if encryWay in ["aes", "sm2"]: + encryWay = input("Choose the way for encryption (aes/sm4): ").strip().lower() # 统一转成小写 + if encryWay in ["aes", "sm4"]: + letterWay = encryWay print(f"You have selected '{encryWay}' encryption.") break # 输入有效后退出循环 else: - print("Invalid choice. Please enter 'aes' or 'sm2'.") + print("Invalid choice. Please enter 'aes' or 'sm4'.") # 选择加密算法的模式 while True: if encryWay == "aes": encryMode = input("Choose the encryption mode (ecb/cbc/cfb/ofb): ").strip().lower() if encryMode in ["ecb", "cbc", "cfb", "ofb"]: + letterMode = encryMode print(f"You have selected '{encryMode}' encryption mode.") break # 输入有效后退出循环 else: print("Invalid choice. Please enter ecb/cbc/cfb/ofb") - elif encryWay == "sm2": - print() - break # 输入有效后退出循环 + elif encryWay == "sm4": + encryMode = input("Choose the encryption mode (ecb/cbc): ").strip().lower() + if encryMode in ["ecb", "cbc"]: + print(f"You have selected '{encryMode}' encryption mode.") + break # 输入有效后退出循环 + else: + print("Invalid choice. Please enter ecb/cbc") return encryWay, encryMode @@ -54,12 +66,18 @@ def SymEncryption(encryData, key: bytes = None): if way == "aes": aesUtils = AESUtils(key) - # tureKey 为 真实返回的Key,如果没有设置初始值,那么key是随机生成 - encryptedData, tureKey = aesUtils.encrypt(encryData, mode=mode) # 这里encryData要改为文件内容 - return encryptedData,tureKey + encryptedData, trueKey = aesUtils.encrypt(encryData, mode=mode) # 这里encryData要改为文件内容 + return encryptedData,trueKey + + if way == "sm4": + key = get_random_bytes(16) + if mode == "ecb": + encrypted_data = encrypt_ecb(data, key) + # mode 为 cbc + else: + encrypted_data = decrypt_cbc_with_iv(data, key) - if way == "sm2": - pass + return encrypted_data, key def getKey(): @@ -69,9 +87,10 @@ def getKey(): if __name__ == "__main__": # 示例数据和密钥 data = "Hello, AES!" - # key = "1234567890abcdef" - print(data) - data,key = SymEncryption(data) + data, akey = SymEncryption(data) + + print(data,akey) - print(data,key) \ No newline at end of file + encryptType = f"{letterWay}_{letterMode}".upper() + print(encryptType) \ No newline at end of file diff --git a/tool/symmetric/AES.py b/tool/symmetric/AES.py index a13d576..8c9a439 100644 --- a/tool/symmetric/AES.py +++ b/tool/symmetric/AES.py @@ -4,21 +4,27 @@ from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes import base64 +from fontTools.misc.eexec import encrypt + class AESUtils: def __init__(self, key: bytes = None): - """初始化 AES 加密工具,如果没有提供密钥,则生成一个随机密钥""" - if key is None: - self.key = get_random_bytes(32) # AES-256 - else: - self.key = key + """生成一个随机密钥""" + self.key = get_random_bytes(32) def encrypt(self, data: str, mode: str = 'ECB') -> (str,str): """加密数据""" cipher = self._get_cipher(mode) data = pad(data.encode(), AES.block_size) # 填充数据 ciphertext = cipher.encrypt(data) - return base64.b64encode(ciphertext).decode(),self.key + return base64.b64encode(ciphertext).decode(), self.key + + def decrypt(self, encrypted_data: str, mode: str = 'ECB') -> str: + """解密数据""" + cipher = self._get_cipher(mode) + encrypted_data = base64.b64decode(encrypted_data) + plaintext = unpad(cipher.decrypt(encrypted_data), AES.block_size) + return plaintext.decode() def _get_cipher(self, mode: str) -> AES: """根据模式返回相应的 AES cipher""" @@ -33,3 +39,12 @@ class AESUtils: else: # 默认是 ECB return AES.new(self.key, AES.MODE_ECB) +if __name__ == "__main__": + # 示例数据和密钥 + data = "Hello, SM4!" + key = "1234567890abcdef" + + enData , akey = AESUtils(key) + + print(enData) + From c7588a9831afdcf12d9945e01f06ca5dbfb11397 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 16:21:56 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8DSM4=E5=92=8CRSA?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/asymmetric/RSA.py | 24 +++++++++++++----------- tool/symmetric/SM4.py | 41 +++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/tool/asymmetric/RSA.py b/tool/asymmetric/RSA.py index 652e4f5..4356b16 100644 --- a/tool/asymmetric/RSA.py +++ b/tool/asymmetric/RSA.py @@ -1,9 +1,10 @@ import base64 import binascii + from Crypto.Cipher import PKCS1_OAEP +from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import pkcs1_15 -from Crypto.Hash import SHA256 def generate_keys(priKeySavePath, pubKeySavePath): @@ -21,45 +22,46 @@ def generate_keys(priKeySavePath, pubKeySavePath): f.write(public_key) -def encrypt_message(message, public_key_base64): +def encrypt_message(message: bytes, public_key_base64): # 加载公钥 public_key_bin = base64.b64decode(public_key_base64) public_key = RSA.import_key(public_key_bin) # 使用公钥加密消息 cipher_rsa = PKCS1_OAEP.new(public_key) - encrypted_message = cipher_rsa.encrypt(message.encode('utf-8')) + encrypted_message = cipher_rsa.encrypt(message) - return binascii.hexlify(encrypted_message).decode('utf-8') + return encrypted_message -def decrypt_message(encrypted_message, private_key_base64): +def decrypt_message(encrypted_message: bytes, private_key_base64): # 加载私钥 private_key_bin = base64.b64decode(private_key_base64) private_key = RSA.import_key(private_key_bin) # 使用私钥解密消息 cipher_rsa = PKCS1_OAEP.new(private_key) - decrypted_message = cipher_rsa.decrypt(binascii.unhexlify(encrypted_message)) + decrypted_message = cipher_rsa.decrypt(encrypted_message) + + return decrypted_message - return decrypted_message.decode('utf-8') -def sign_message(message, private_key_base64): +def sign_message(message: bytes, private_key_base64): # 加载私钥 private_key_bin = base64.b64decode(private_key_base64) private_key = RSA.import_key(private_key_bin) # 计算消息的哈希值 - hash_obj = SHA256.new(message.encode('utf-8')) + hash_obj = SHA256.new(message) # 使用私钥对哈希值进行签名 signature = pkcs1_15.new(private_key).sign(hash_obj) return binascii.hexlify(signature).decode('utf-8') -def verify_signature(message, signature, public_key_base64): +def verify_signature(message: bytes, signature, public_key_base64): # 加载公钥 public_key_bin = base64.b64decode(public_key_base64) public_key = RSA.import_key(public_key_bin) # 计算消息的哈希值 - hash_obj = SHA256.new(message.encode('utf-8')) + hash_obj = SHA256.new(message) # 使用公钥验证签名 try: pkcs1_15.new(public_key).verify(hash_obj, binascii.unhexlify(signature)) diff --git a/tool/symmetric/SM4.py b/tool/symmetric/SM4.py index d3d53e1..f68e222 100644 --- a/tool/symmetric/SM4.py +++ b/tool/symmetric/SM4.py @@ -2,49 +2,54 @@ import os from gmssl import sm4 + def encrypt_ecb(data, key): cipher = sm4.CryptSM4() - cipher.set_key(key.encode('utf-8'), sm4.SM4_ENCRYPT) - encrypted_data = cipher.crypt_ecb(data.encode('utf-8')) - return encrypted_data.hex() + cipher.set_key(key, sm4.SM4_ENCRYPT) + encrypted_data = cipher.crypt_ecb(data) + return encrypted_data + -def decrypt_ecb(encrypted_hex, key): +def decrypt_ecb(encrypted_data, key): cipher = sm4.CryptSM4() - cipher.set_key(key.encode('utf-8'), sm4.SM4_DECRYPT) - decrypted_data = cipher.crypt_ecb(bytes.fromhex(encrypted_hex)) - return decrypted_data.decode('utf-8') + cipher.set_key(key, sm4.SM4_DECRYPT) + decrypted_data = cipher.crypt_ecb(encrypted_data) + return decrypted_data + def encrypt_cbc_with_iv(data, key): cipher = sm4.CryptSM4() - cipher.set_key(key.encode('utf-8'), sm4.SM4_ENCRYPT) + cipher.set_key(key, sm4.SM4_ENCRYPT) # 生成随机的16字节IV iv = os.urandom(16) # 加密数据 - encrypted_data = cipher.crypt_cbc(iv, data.encode('utf-8')) + encrypted_data = cipher.crypt_cbc(iv, data) # 将IV和加密后的数据拼接在一起 return iv + encrypted_data -def decrypt_cbc_with_iv(encrypted_bytes, key): + +def decrypt_cbc_with_iv(encrypted_data, key): cipher = sm4.CryptSM4() - cipher.set_key(key.encode('utf-8'), sm4.SM4_DECRYPT) + cipher.set_key(key, sm4.SM4_DECRYPT) # 提取IV - iv = encrypted_bytes[:16] + iv = encrypted_data[:16] # 提取加密后的数据 - encrypted_data = encrypted_bytes[16:] + encrypted_data = encrypted_data[16:] # 解密数据 decrypted_data = cipher.crypt_cbc(iv, encrypted_data) - return decrypted_data.decode('utf-8') + return decrypted_data + if __name__ == "__main__": # 示例数据和密钥 - data = "Hello, SM4!" - key = "1234567890abcdef" + data = b"Hello, SM4!" + key = b"1234567890abcdef" # 加密 encrypted_data = encrypt_ecb(data, key) @@ -55,8 +60,8 @@ if __name__ == "__main__": print(f"Decrypted: {decrypted_data}") # 示例数据和密钥 - data = "Hello, SM4 CBC with random IV!" - key = "1234567890abcdef" + data = b"Hello, SM4 CBC with random IV!" + key = b"1234567890abcdef" # 加密 encrypted_data = encrypt_cbc_with_iv(data, key) From 730fb4dd9628ec1a428d7043a24e4ea7deadb3b2 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 16:37:58 +0800 Subject: [PATCH 07/12] =?UTF-8?q?SM4=E7=9A=84message=E4=BD=BF=E7=94=A8str?= =?UTF-8?q?=EF=BC=8Ckey=E4=BD=BF=E7=94=A8bytes=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tool/symmetric/SM4.py | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/tool/symmetric/SM4.py b/tool/symmetric/SM4.py index f68e222..38ee3ec 100644 --- a/tool/symmetric/SM4.py +++ b/tool/symmetric/SM4.py @@ -1,23 +1,30 @@ +import base64 import os from gmssl import sm4 - - -def encrypt_ecb(data, key): +""" +输入: +消息或者加密后消息:字符串类型 +key:字节类型 +输出: +消息或者加密后消息:base64的字符串类型 +""" + +def encrypt_ecb(data: str, key: bytes) -> str: cipher = sm4.CryptSM4() cipher.set_key(key, sm4.SM4_ENCRYPT) - encrypted_data = cipher.crypt_ecb(data) - return encrypted_data + encrypted_data = cipher.crypt_ecb(data.encode('utf-8')) + return base64.b64encode(encrypted_data).decode('utf-8') -def decrypt_ecb(encrypted_data, key): +def decrypt_ecb(encrypted_hex: str, key: bytes) -> str: cipher = sm4.CryptSM4() cipher.set_key(key, sm4.SM4_DECRYPT) - decrypted_data = cipher.crypt_ecb(encrypted_data) - return decrypted_data + decrypted_data = cipher.crypt_ecb(bytes.fromhex(encrypted_hex)) + return decrypted_data.decode('utf-8') -def encrypt_cbc_with_iv(data, key): +def encrypt_cbc_with_iv(data: str, key: bytes) -> str: cipher = sm4.CryptSM4() cipher.set_key(key, sm4.SM4_ENCRYPT) @@ -25,30 +32,31 @@ def encrypt_cbc_with_iv(data, key): iv = os.urandom(16) # 加密数据 - encrypted_data = cipher.crypt_cbc(iv, data) + encrypted_data = cipher.crypt_cbc(iv, data.encode('utf-8')) # 将IV和加密后的数据拼接在一起 - return iv + encrypted_data + return base64.b64encode(iv + encrypted_data).decode('utf-8') -def decrypt_cbc_with_iv(encrypted_data, key): +def decrypt_cbc_with_iv(encrypted_bytes_base64: str, key) -> str: + encrypted_bytes = base64.b64decode(encrypted_bytes_base64) cipher = sm4.CryptSM4() cipher.set_key(key, sm4.SM4_DECRYPT) # 提取IV - iv = encrypted_data[:16] + iv = encrypted_bytes[:16] # 提取加密后的数据 - encrypted_data = encrypted_data[16:] + encrypted_data = encrypted_bytes[16:] # 解密数据 decrypted_data = cipher.crypt_cbc(iv, encrypted_data) - return decrypted_data + return base64.b64decode(decrypted_data).decode('utf-8') if __name__ == "__main__": # 示例数据和密钥 - data = b"Hello, SM4!" + data = "Hello, SM4!" key = b"1234567890abcdef" # 加密 @@ -60,7 +68,7 @@ if __name__ == "__main__": print(f"Decrypted: {decrypted_data}") # 示例数据和密钥 - data = b"Hello, SM4 CBC with random IV!" + data = "Hello, SM4 CBC with random IV!" key = b"1234567890abcdef" # 加密 From 0c0bce2095c1f8adce55e0087d29a632c231f073 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 16:40:32 +0800 Subject: [PATCH 08/12] =?UTF-8?q?SM4=E7=9A=84message=E4=BD=BF=E7=94=A8str?= =?UTF-8?q?=EF=BC=8Ckey=E4=BD=BF=E7=94=A8bytes=E7=B1=BB=E5=9E=8B=20RSA?= =?UTF-8?q?=E5=88=99=E5=85=A8=E7=A8=8B=E4=BD=BF=E7=94=A8bytes=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/Letter.py | 2 +- tool/asymmetric/RSA.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/entity/Letter.py b/entity/Letter.py index e5b4113..5a05a92 100644 --- a/entity/Letter.py +++ b/entity/Letter.py @@ -1,7 +1,7 @@ class Letter: sign = "计算得到" encryptType = "SM4-GCM" - encryptKey = "计算获得" + encryptKey = "计算获得" # recvPubKey 加密后的 对称加密秘钥 数据 recvPubKey = "" senderPubKey = "" diff --git a/tool/asymmetric/RSA.py b/tool/asymmetric/RSA.py index 4356b16..f6bdc49 100644 --- a/tool/asymmetric/RSA.py +++ b/tool/asymmetric/RSA.py @@ -21,7 +21,13 @@ def generate_keys(priKeySavePath, pubKeySavePath): with open(pubKeySavePath, "wb") as f: f.write(public_key) - +""" +输入: +需要公私钥加解密的消息:字节类型 +公私钥:base64 +输出: +加解密后的数据:字节类型 +""" def encrypt_message(message: bytes, public_key_base64): # 加载公钥 public_key_bin = base64.b64decode(public_key_base64) From 49fb76fe56efe9cefc07319a262223972a437fe5 Mon Sep 17 00:00:00 2001 From: UniDarkstars <1830018670@qq.com> Date: Sun, 24 Nov 2024 19:46:12 +0800 Subject: [PATCH 09/12] =?UTF-8?q?sender=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8CRSA=E4=BF=AE=E6=94=B9=E4=BA=86encryp?= =?UTF-8?q?t=5Fmessage=E4=B8=ADcipher=5Frsa.encrypt(message)=EF=BC=8C?= =?UTF-8?q?=E5=8E=9F=E6=9C=ACmessage.encode('utf-8')?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sender/sender.py | 78 ++++++++++++++++++++++++++++++++++++------ tool/asymmetric/RSA.py | 2 +- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/sender/sender.py b/sender/sender.py index 9915251..bfcf195 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,15 +1,37 @@ # 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 +from encodings.base64_codec import base64_encode from entity.Letter import Letter +from tool import PriKeyHelper +from tool.PriKeyHelper import getUserKey +from tool.asymmetric import RSA from tool.symmetric.AES import AESUtils from tool.symmetric.SM4 import encrypt_ecb, decrypt_cbc_with_iv from Crypto.Random import get_random_bytes + # 两个变量,记录信封 letterWay = "" letterMode = "" +letterSymKey = "" def main(): # 用户输入各种数据填充letter字段 + data = "Hello, AES!" + + data, akey = SymEncryption(data) + + Letter.sign = getSign() + Letter.encryptType = getEncryptType() + Letter.encryptKey = getEncryptKey() + Letter.recvPubKey = getRecvPubKey() + Letter.senderPubKey = getSenderPubKey() + + print(Letter.sign) + print(Letter.encryptType) + print(Letter.encryptKey) + print(Letter.recvPubKey) + print(Letter.senderPubKey) + # 获取用户的公私钥对进行签名 # 使用对方的公钥进行加密 # 发送信件 @@ -61,36 +83,72 @@ def selectSymEncryptionChoice(): # 使用对称加密,返回加密后的数据和随机生成的密钥 def SymEncryption(encryData, key: bytes = None): + + global letterSymKey # 获得加密的方法和加密的模式 way, mode = selectSymEncryptionChoice() if way == "aes": aesUtils = AESUtils(key) encryptedData, trueKey = aesUtils.encrypt(encryData, mode=mode) # 这里encryData要改为文件内容 + letterSymKey = trueKey + return encryptedData,trueKey if way == "sm4": key = get_random_bytes(16) if mode == "ecb": - encrypted_data = encrypt_ecb(data, key) + encrypted_data = encrypt_ecb(encryData, key) # mode 为 cbc else: - encrypted_data = decrypt_cbc_with_iv(data, key) + encrypted_data = decrypt_cbc_with_iv(encryData, key) + + letterSymKey = key return encrypted_data, key +# 获得签名 +def getSign(): -def getKey(): - pass + #计算文件bytes + document_bytes = "" + priKey, pubKey = PriKeyHelper.getUserKey() + signDocuHash = RSA.sign_message(document_bytes, priKey) + + return signDocuHash + +def getEncryptType(): + encryType = f"{letterWay}_{letterMode}".upper() + + return encryType + +# 对称密钥,返回的是使用接收方公钥加密后的密钥 +def getEncryptKey(): + rsaEncrySymKey = RSA.encrypt_message(letterSymKey, getRecvPubKey()) + + return rsaEncrySymKey + +# 获得接收方的公钥 +def getRecvPubKey(): + # recPubKey = input("plz input Receiver's Public Key: ") + recPubKey = getUserKey()[1] + return recPubKey + +# 获得发送方的公钥 +def getSenderPubKey(): + privateKey, publicKey = getUserKey() + return publicKey if __name__ == "__main__": # 示例数据和密钥 - data = "Hello, AES!" - - data, akey = SymEncryption(data) + # data = "Hello, AES!" + # + # data, akey = SymEncryption(data) - print(data,akey) + # print(data,akey) + # + # encryptType = f"{letterWay}_{letterMode}".upper() + # print(encryptType) - encryptType = f"{letterWay}_{letterMode}".upper() - print(encryptType) \ No newline at end of file + main() \ No newline at end of file diff --git a/tool/asymmetric/RSA.py b/tool/asymmetric/RSA.py index 652e4f5..542418d 100644 --- a/tool/asymmetric/RSA.py +++ b/tool/asymmetric/RSA.py @@ -27,7 +27,7 @@ def encrypt_message(message, public_key_base64): public_key = RSA.import_key(public_key_bin) # 使用公钥加密消息 cipher_rsa = PKCS1_OAEP.new(public_key) - encrypted_message = cipher_rsa.encrypt(message.encode('utf-8')) + encrypted_message = cipher_rsa.encrypt(message) return binascii.hexlify(encrypted_message).decode('utf-8') From 4f0f01a1d158e86a6dff6fd4e9fcdbaaafc58f64 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 20:04:56 +0800 Subject: [PATCH 10/12] =?UTF-8?q?sender=20=E4=BF=AE=E6=AD=A3=20=E5=87=86?= =?UTF-8?q?=E5=A4=87=E5=AF=B9=E6=8E=A5Letter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/Letter.py | 1 - sender/sender.py | 43 +++++++++++++++++++++++++------------------ tool/symmetric/SM4.py | 6 +++--- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/entity/Letter.py b/entity/Letter.py index e0bcf97..5f57d59 100644 --- a/entity/Letter.py +++ b/entity/Letter.py @@ -6,5 +6,4 @@ class Letter: senderPubKey = "" fileName = "" - fileSize = 0 fileBase64 = "" diff --git a/sender/sender.py b/sender/sender.py index bfcf195..ca50838 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,42 +1,51 @@ # 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 -from encodings.base64_codec import base64_encode from entity.Letter import Letter from tool import PriKeyHelper from tool.PriKeyHelper import getUserKey from tool.asymmetric import RSA from tool.symmetric.AES import AESUtils -from tool.symmetric.SM4 import encrypt_ecb, decrypt_cbc_with_iv +from tool.symmetric.SM4 import encrypt_ecb, decrypt_cbc_with_iv, encrypt_cbc_with_iv from Crypto.Random import get_random_bytes # 两个变量,记录信封 letterWay = "" letterMode = "" -letterSymKey = "" +letterSymKey = b"" def main(): + letter = Letter() # 用户输入各种数据填充letter字段 - data = "Hello, AES!" + path = selectFile() + + with open(path,"rb") as f: + data = f.read() + letter.fileName = "交给你了" + letter.encryptType = getEncryptType() + letter.encryptKey = getEncryptKey() + letter.recvPubKey = getRecvPubKey() + letter.senderPubKey = getSenderPubKey() + SymEncryption(data,letterSymKey) + # data = "Hello, AES!" data, akey = SymEncryption(data) + letter.sign = getSign() + - Letter.sign = getSign() - Letter.encryptType = getEncryptType() - Letter.encryptKey = getEncryptKey() - Letter.recvPubKey = getRecvPubKey() - Letter.senderPubKey = getSenderPubKey() - print(Letter.sign) - print(Letter.encryptType) - print(Letter.encryptKey) - print(Letter.recvPubKey) - print(Letter.senderPubKey) + print(letter.sign) + print(letter.encryptType) + print(letter.encryptKey) + print(letter.recvPubKey) + print(letter.senderPubKey) # 获取用户的公私钥对进行签名 # 使用对方的公钥进行加密 # 发送信件 pass - +def selectFile() -> str: + s = input("输入文件路径:") + return s def sendLetter(letter: Letter, target="192.168.195.162:8426"): # 向目标ip和端口发送指定的信件 @@ -101,10 +110,8 @@ def SymEncryption(encryData, key: bytes = None): encrypted_data = encrypt_ecb(encryData, key) # mode 为 cbc else: - encrypted_data = decrypt_cbc_with_iv(encryData, key) - + encrypted_data = encrypt_cbc_with_iv(encryData, key) letterSymKey = key - return encrypted_data, key # 获得签名 diff --git a/tool/symmetric/SM4.py b/tool/symmetric/SM4.py index 38ee3ec..30eb982 100644 --- a/tool/symmetric/SM4.py +++ b/tool/symmetric/SM4.py @@ -20,7 +20,7 @@ def encrypt_ecb(data: str, key: bytes) -> str: def decrypt_ecb(encrypted_hex: str, key: bytes) -> str: cipher = sm4.CryptSM4() cipher.set_key(key, sm4.SM4_DECRYPT) - decrypted_data = cipher.crypt_ecb(bytes.fromhex(encrypted_hex)) + decrypted_data = cipher.crypt_ecb(base64.b64decode(encrypted_hex)) return decrypted_data.decode('utf-8') @@ -51,7 +51,7 @@ def decrypt_cbc_with_iv(encrypted_bytes_base64: str, key) -> str: # 解密数据 decrypted_data = cipher.crypt_cbc(iv, encrypted_data) - return base64.b64decode(decrypted_data).decode('utf-8') + return decrypted_data.decode("utf-8") if __name__ == "__main__": @@ -73,7 +73,7 @@ if __name__ == "__main__": # 加密 encrypted_data = encrypt_cbc_with_iv(data, key) - print(f"Encrypted: {encrypted_data.hex()}") + print(f"Encrypted: {encrypted_data}") # 解密 decrypted_data = decrypt_cbc_with_iv(encrypted_data, key) From 713105b87c73b6cb22bfe09280683d35acdeebe1 Mon Sep 17 00:00:00 2001 From: UniDarkstars <1830018670@qq.com> Date: Sun, 24 Nov 2024 20:15:01 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86sender?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sender/sender.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sender/sender.py b/sender/sender.py index ca50838..d30a1b2 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,5 +1,6 @@ # 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 from entity.Letter import Letter +from itsdangerous import base64_encode from tool import PriKeyHelper from tool.PriKeyHelper import getUserKey from tool.asymmetric import RSA @@ -25,10 +26,9 @@ def main(): letter.encryptKey = getEncryptKey() letter.recvPubKey = getRecvPubKey() letter.senderPubKey = getSenderPubKey() - SymEncryption(data,letterSymKey) + data, akey = SymEncryption(base64_encode(data).decode("utf-8"),letterSymKey) # data = "Hello, AES!" - data, akey = SymEncryption(data) letter.sign = getSign() @@ -39,6 +39,7 @@ def main(): print(letter.recvPubKey) print(letter.senderPubKey) + # 获取用户的公私钥对进行签名 # 使用对方的公钥进行加密 # 发送信件 @@ -133,7 +134,7 @@ def getEncryptType(): def getEncryptKey(): rsaEncrySymKey = RSA.encrypt_message(letterSymKey, getRecvPubKey()) - return rsaEncrySymKey + return base64_encode(rsaEncrySymKey).decode("utf-8") # 获得接收方的公钥 def getRecvPubKey(): From 26890907007c737de5b7dda590ddcf60d551d629 Mon Sep 17 00:00:00 2001 From: Timmoc Date: Sun, 24 Nov 2024 20:42:16 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E6=9C=89=E5=B1=8E=E5=95=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修了一点okToCheck的代码,反正现在test_recv跑通了,剩下的都是小事了。 准备把这坨大的合并到main分支 --- .gitignore | 5 +++++ recv/recv.py | 14 +++++++------- recv/test_recv.py | 11 ++++++++--- sender/sender.py | 17 ++++++++++------- tool/test_PriKeyHelper.py | 4 ++-- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 56c7dcd..d23cf10 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,8 @@ /tool/private.pem /private.pem /public.pem +/sender/private.pem +/recv/private.pem +/recv/public.pem +/sender/public.pem +/recv/交给你了 diff --git a/recv/recv.py b/recv/recv.py index ac101ff..5bf5675 100644 --- a/recv/recv.py +++ b/recv/recv.py @@ -22,19 +22,19 @@ def handleLetter(letter:Letter): if pki[1] != letter.recvPubKey: raise Exception("信件不属于自己") # 用自己的私钥解密key 获得对称加密秘钥。 - key = RSA.decrypt_message(letter.encryptKey,pki[0]) + key = RSA.decrypt_message(base64.b64decode(letter.encryptKey),pki[0]) # 根据不同的对称加密算法 try: type = config.getEncryptType(letter.encryptType) - except KeyError: - raise KeyError("不支持的对称加密算法") + except ValueError: + raise ValueError("不支持的对称加密算法") # 进行解密fileBase64 - data = None + data = b"" if type == config.EncryptType.SM4_ECB: - SM4.decrypt_ecb(base64.b64decode(letter.fileBase64),key) + data = base64.b64decode(SM4.decrypt_ecb(letter.fileBase64,key)) elif type == config.EncryptType.SM4_CBC: - SM4.decrypt_cbc_with_iv(base64.b64decode(letter.fileBase64),key) + data = base64.b64decode(SM4.decrypt_cbc_with_iv(letter.fileBase64,key)) elif type == config.EncryptType.AES_ECB: raise NotImplementedError("未实现") elif type == config.EncryptType.AES_CBC: @@ -50,5 +50,5 @@ def handleLetter(letter:Letter): # 保存文件 with open(f"./{letter.fileName}","wb") as f: f.write(data) - + print(f"签名验证有效,已将文件 {letter.fileName} 保存至当前目录下") return \ No newline at end of file diff --git a/recv/test_recv.py b/recv/test_recv.py index 26601b1..ca0ad29 100644 --- a/recv/test_recv.py +++ b/recv/test_recv.py @@ -1,8 +1,13 @@ +from unittest.mock import patch + +import recv from sender import sender from tool import PriKeyHelper -def test_handleLetter(): +@patch('builtins.input', side_effect=['./public.pem', 'sm4', 'cbc']) +def test_handleLetter(mock_input): pki = PriKeyHelper.getUserKey() - - pass \ No newline at end of file + letter = sender.main() + recv.handleLetter(letter) + pass diff --git a/sender/sender.py b/sender/sender.py index d30a1b2..27127fc 100644 --- a/sender/sender.py +++ b/sender/sender.py @@ -1,4 +1,6 @@ # 模式,文件,自己的公钥从哪里来,别人的公钥从哪里来 +import base64 + from entity.Letter import Letter from itsdangerous import base64_encode from tool import PriKeyHelper @@ -22,14 +24,14 @@ def main(): with open(path,"rb") as f: data = f.read() letter.fileName = "交给你了" - letter.encryptType = getEncryptType() - letter.encryptKey = getEncryptKey() letter.recvPubKey = getRecvPubKey() letter.senderPubKey = getSenderPubKey() - data, akey = SymEncryption(base64_encode(data).decode("utf-8"),letterSymKey) + letter.fileBase64, akey = SymEncryption(base64_encode(data).decode("utf-8"),letterSymKey) # data = "Hello, AES!" + letter.encryptKey = getEncryptKey() + letter.encryptType = getEncryptType() - letter.sign = getSign() + letter.sign = getSign(data) @@ -43,6 +45,7 @@ def main(): # 获取用户的公私钥对进行签名 # 使用对方的公钥进行加密 # 发送信件 + return letter # 方便recv测试,以后可以删除。 pass def selectFile() -> str: s = input("输入文件路径:") @@ -83,6 +86,7 @@ def selectSymEncryptionChoice(): elif encryWay == "sm4": encryMode = input("Choose the encryption mode (ecb/cbc): ").strip().lower() if encryMode in ["ecb", "cbc"]: + letterMode = encryMode print(f"You have selected '{encryMode}' encryption mode.") break # 输入有效后退出循环 else: @@ -116,10 +120,9 @@ def SymEncryption(encryData, key: bytes = None): return encrypted_data, key # 获得签名 -def getSign(): +def getSign(document_bytes): #计算文件bytes - document_bytes = "" priKey, pubKey = PriKeyHelper.getUserKey() signDocuHash = RSA.sign_message(document_bytes, priKey) @@ -134,7 +137,7 @@ def getEncryptType(): def getEncryptKey(): rsaEncrySymKey = RSA.encrypt_message(letterSymKey, getRecvPubKey()) - return base64_encode(rsaEncrySymKey).decode("utf-8") + return base64.b64encode(rsaEncrySymKey).decode("utf-8") # 获得接收方的公钥 def getRecvPubKey(): diff --git a/tool/test_PriKeyHelper.py b/tool/test_PriKeyHelper.py index 8de5054..ed34aa4 100644 --- a/tool/test_PriKeyHelper.py +++ b/tool/test_PriKeyHelper.py @@ -6,7 +6,7 @@ from tool.asymmetric import RSA def test_encrypt(): key = PriKeyHelper.getUserKey() - message = "Hello, this is a secret message." + message = b"Hello, this is a secret message." # 打印keys print(key[0]) print(key[1]) @@ -23,7 +23,7 @@ def test_encrypt(): def test_sign(): key = PriKeyHelper.getUserKey() - message = "This is a signed message." + message = b"This is a signed message." # 打印keys print(key[0]) print(key[1])