两个用户之间的消息加密
Message encryption between two users
我正在编写 python 脚本只是为了练习密码学。我想创建一个小程序,用户可以向自己发送必须加密和解密的消息。我创建了 3 classes。第一个包含 2 个函数,我可以使用 encrypt
和 decrypt
使用 public 和私钥发送消息。第二个class是Message
class,它有4个属性(sender
,消息的text
,recipient
和一个timestamp
)。使用 class 方法 __str__
,我创建了必须以这种格式发送的实际消息:From {the name of the sender}: {Message} {timestamp}
。第三个class是User
。使用 User
,我可以使用 name
、public
和 private
密钥初始化每个用户,一个接收加密消息的收件箱和一个名为 messages 的列表来存储收到的每条消息和解密。每个用户都可以通过使用收件人的 public 密钥加密消息来将消息发送给另一个用户,然后收件人可以使用自己的私钥解密加密的消息。我想通过使用 2 个函数 send
来完成此操作,这两个函数会对消息进行加密并将其发送到收件人的收件箱中。此函数必须由发件人使用,send
函数 运行 是收件人的 receive
函数,它遍历新消息,decrypts
和 appends
消息 (From {sender.name} ...
) 到消息列表。
然后我尝试通过创建 2 个用户(Bob 和 Alice)来 运行 程序并发送一些消息。但是我遇到了一些错误。
我尝试使用 encrypt
和 decrypt
函数来加密和解密一个简单的字符串(没有用户和我添加的其他东西)并且确实有效。
我在这里找到了两个函数(加密和解密):https://medium.com/@securegns/implementing-asymmetric-encryption-to-secure-your-project-35368049cb5f
我是密码学的绝对初学者,我可能使用了错误的做法。
可能是什么问题?我想不通
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(cipher_text)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
plain_text = private_key.decrypt(decoded_ciphertext)
return plain_text
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
错误
File "\encrypt.py", line 59, in send
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
File \encrypt.py", line 11, in encrypt
cipher_text = public_key.encrypt(text, 32)[0]
File "Crypto\PublicKey\RSA.py", line 150, in encrypt
return pubkey.pubkey.encrypt(self, plaintext, K)
File "\Crypto\PublicKey\pubkey.py", line 75, in encrypt
ciphertext=self._encrypt(plaintext, K)
File "\Crypto\PublicKey\RSA.py", line 224, in _encrypt
return (self.key._encrypt(c),)
File "\Crypto\PublicKey\_slowmath.py", line 65, in _encrypt
return pow(m, self.e, self.n)
TypeError: unsupported operand type(s) for pow(): 'str', 'int', 'int'
解决方案
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
oaep = PKCS1_OAEP.new(public_key, SHA256)
ciphertext = oaep.encrypt(bytes(text, encoding="ASCII"))
# cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(ciphertext)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
oaep = PKCS1_OAEP.new(private_key, SHA256)
plaintext = oaep.decrypt(decoded_ciphertext)
# plain_text = private_key.decrypt(decoded_ciphertext)
print("Decrypted Plaintext: {}".format(plaintext))
return plaintext
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
您是否正在使用 https://github.com/pycrypto/pycrypto 并且您的 python 版本是 >3.5?
它说 PyCrypto 是使用 Python 版本 2.1 到 3.3 编写和测试的。
请更新至https://github.com/Legrandin/pycryptodome,然后查看是否有效。
第二个库负责在调用 pow() 之前转换为 Integar。
第一个也在 this file 中进行了检查,但他们似乎正在使用 types.StringType,在 python 2.7 之后不再存在。他们在安装过程中使用 2to3 使其与 python3 一起使用,但 types.StringType 转换为字节,但在最新的 python.
上失败
-if isinstance(plaintext, types.StringType):
+if isinstance(plaintext, bytes):
同时检查 this reddit post 是否有其他加密库
这是你修改后的代码
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
oaep = PKCS1_OAEP.new(public_key, SHA256)
ciphertext = oaep.encrypt(bytes(text, encoding="ASCII"))
# cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(ciphertext)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
oaep = PKCS1_OAEP.new(private_key, SHA256)
plaintext = oaep.decrypt(decoded_ciphertext)
# plain_text = private_key.decrypt(decoded_ciphertext)
print("Decrypted Plaintext: {}".format(plaintext))
return plaintext
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
它打印出正确的明文。我使用 OAEP
进行加密和解密,因为不建议在 RSA
中单独加密明文,因为 RSA 具有延展性,因此必须使用为明文添加一些随机性的加密,请参阅此 link.
我正在编写 python 脚本只是为了练习密码学。我想创建一个小程序,用户可以向自己发送必须加密和解密的消息。我创建了 3 classes。第一个包含 2 个函数,我可以使用 encrypt
和 decrypt
使用 public 和私钥发送消息。第二个class是Message
class,它有4个属性(sender
,消息的text
,recipient
和一个timestamp
)。使用 class 方法 __str__
,我创建了必须以这种格式发送的实际消息:From {the name of the sender}: {Message} {timestamp}
。第三个class是User
。使用 User
,我可以使用 name
、public
和 private
密钥初始化每个用户,一个接收加密消息的收件箱和一个名为 messages 的列表来存储收到的每条消息和解密。每个用户都可以通过使用收件人的 public 密钥加密消息来将消息发送给另一个用户,然后收件人可以使用自己的私钥解密加密的消息。我想通过使用 2 个函数 send
来完成此操作,这两个函数会对消息进行加密并将其发送到收件人的收件箱中。此函数必须由发件人使用,send
函数 运行 是收件人的 receive
函数,它遍历新消息,decrypts
和 appends
消息 (From {sender.name} ...
) 到消息列表。
然后我尝试通过创建 2 个用户(Bob 和 Alice)来 运行 程序并发送一些消息。但是我遇到了一些错误。
我尝试使用 encrypt
和 decrypt
函数来加密和解密一个简单的字符串(没有用户和我添加的其他东西)并且确实有效。
我在这里找到了两个函数(加密和解密):https://medium.com/@securegns/implementing-asymmetric-encryption-to-secure-your-project-35368049cb5f
我是密码学的绝对初学者,我可能使用了错误的做法。
可能是什么问题?我想不通
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(cipher_text)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
plain_text = private_key.decrypt(decoded_ciphertext)
return plain_text
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
错误
File "\encrypt.py", line 59, in send
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
File \encrypt.py", line 11, in encrypt
cipher_text = public_key.encrypt(text, 32)[0]
File "Crypto\PublicKey\RSA.py", line 150, in encrypt
return pubkey.pubkey.encrypt(self, plaintext, K)
File "\Crypto\PublicKey\pubkey.py", line 75, in encrypt
ciphertext=self._encrypt(plaintext, K)
File "\Crypto\PublicKey\RSA.py", line 224, in _encrypt
return (self.key._encrypt(c),)
File "\Crypto\PublicKey\_slowmath.py", line 65, in _encrypt
return pow(m, self.e, self.n)
TypeError: unsupported operand type(s) for pow(): 'str', 'int', 'int'
解决方案
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
oaep = PKCS1_OAEP.new(public_key, SHA256)
ciphertext = oaep.encrypt(bytes(text, encoding="ASCII"))
# cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(ciphertext)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
oaep = PKCS1_OAEP.new(private_key, SHA256)
plaintext = oaep.decrypt(decoded_ciphertext)
# plain_text = private_key.decrypt(decoded_ciphertext)
print("Decrypted Plaintext: {}".format(plaintext))
return plaintext
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
您是否正在使用 https://github.com/pycrypto/pycrypto 并且您的 python 版本是 >3.5? 它说 PyCrypto 是使用 Python 版本 2.1 到 3.3 编写和测试的。
请更新至https://github.com/Legrandin/pycryptodome,然后查看是否有效。 第二个库负责在调用 pow() 之前转换为 Integar。
第一个也在 this file 中进行了检查,但他们似乎正在使用 types.StringType,在 python 2.7 之后不再存在。他们在安装过程中使用 2to3 使其与 python3 一起使用,但 types.StringType 转换为字节,但在最新的 python.
上失败-if isinstance(plaintext, types.StringType):
+if isinstance(plaintext, bytes):
同时检查 this reddit post 是否有其他加密库
这是你修改后的代码
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
import base64
import datetime
class Crypt:
@staticmethod
def encrypt(public_key, text):
oaep = PKCS1_OAEP.new(public_key, SHA256)
ciphertext = oaep.encrypt(bytes(text, encoding="ASCII"))
# cipher_text = public_key.encrypt(text, 32)[0]
b64cipher = base64.b64encode(ciphertext)
return b64cipher
@staticmethod
def decrypt(private_key, b64cipher):
decoded_ciphertext = base64.b64decode(b64cipher)
oaep = PKCS1_OAEP.new(private_key, SHA256)
plaintext = oaep.decrypt(decoded_ciphertext)
# plain_text = private_key.decrypt(decoded_ciphertext)
print("Decrypted Plaintext: {}".format(plaintext))
return plaintext
class Message:
def __init__(self, sender, txt, recipient):
self.sender = sender
self.txt = txt
self.recipient = recipient
self.timestamp = datetime.datetime.now().date()
def __str__(self):
return f"From {self.sender}: {self.txt} {self.timestamp}"
class User:
def __init__(self, name):
random = Random.new().read
self.name = name
self.private_key = RSA.generate(1024, random)
self.public_key = self.private_key.publickey()
self.inbox = []
self.messages = []
def receive(self):
# Decrypts encrypted messages in the inbox and transfers the decrypted messages into the messages
list
for i in self.inbox:
message = Crypt.decrypt(self.private_key, i)
self.messages.append(message)
self.inbox.pop()
return self.messages
def send(self, msg, recipient):
# User use send function and encrypts the message with the recipient's public key and appends into the recipient's inbox the encrypted message
message = Message(self.name, msg, recipient)
b64cipher = Crypt.encrypt(recipient.public_key, message.__str__())
self.messages.append(message.__str__())
recipient.inbox.append(b64cipher)
recipient.receive()
Bob = User("Bob")
Alice = User("Alice")
Bob.send("Hi", Alice)
Alice.send("Hi Bob!", Bob)
Bob.send("How are you?", Alice)
它打印出正确的明文。我使用 OAEP
进行加密和解密,因为不建议在 RSA
中单独加密明文,因为 RSA 具有延展性,因此必须使用为明文添加一些随机性的加密,请参阅此 link.