RSA加密数据将从字节转换为字符串,然后返回字节?
我正在尝试通过套接字通信在多个客户端之间使用公钥加密来实现对称密钥协议方案,并且我一直在测试加密和解密功能。
import rsa
def generateAKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/APubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/APrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def generateBKeys():
(publicKey, privateKey) = rsa.newkeys(1024)
with open('keys/BPubKey.pem', 'wb') as p:
p.write(publicKey.save_pkcs1('PEM'))
with open('keys/BPrivKey.pem', 'wb') as p:
p.write(privateKey.save_pkcs1('PEM'))
def loadKeys():
with open('keys/APubKey.pem', 'rb') as p:
APubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/APrivKey.pem', 'rb') as p:
APrivKey = rsa.PrivateKey.load_pkcs1(p.read())
with open('keys/BPubKey.pem', 'rb') as p:
BPubKey = rsa.PublicKey.load_pkcs1(p.read())
with open('keys/BPrivKey.pem', 'rb') as p:
BPrivKey = rsa.PrivateKey.load_pkcs1(p.read())
return APubKey, APrivKey, BPubKey, BPrivKey
def encrypt(message, key):
return rsa.encrypt(message.encode('utf8'), key)
def decrypt(ciphertext, key):
try:
return rsa.decrypt(ciphertext, key).decode('utf8')
except:
return False
def sign(message, key):
return rsa.sign(message.encode('utf8'), key, 'SHA-1')
def verify(message, signature, key):
try:
return rsa.verify(message.encode('utf8'), signature, key,) == 'SHA-1'
except:
return False
APubKey, APrivKey, BPubKey, BPrivKey = loadKeys()
message = 'Hello'
ciphertext = encrypt(message, BPubKey)
print(ciphertext)
print(type(ciphertext))
signature = sign(message, APrivKey)
message1 = "{}|{}".format(ciphertext, signature)
#Simulating message transfer over socket
message2 = message1 #Recived Messgae
message2 = message2.split("|")
ciphertext1, signature1 = message2[0], message2[1]
print(ciphertext1)
print(type(ciphertext1))
print(ciphertext == ciphertext1)
plaintext = decrypt(ciphertext1, BPrivKey)
if plaintext:
print(f'Message text: {plaintext}')
else:
print(f'Unable to decrypt the message.')
if verify(plaintext, signature1, APubKey):
print('Successfully verified signature')
else:
print('The message signature could not be verified')
客户端之间来回发送的信息采用以下格式打包 message1 = "{}|{}".format(ciphertext,signature)
,该格式允许消息被拆分和读取单独的部分。在这个文件中,我只是将消息打包成这种格式,以模拟客户端之间的传输。
我的问题是,一旦创建加密消息(以字节为单位)并打包成上面所示的格式,它就会转换为字符串。当我尝试提取该加密消息并解密它时,我无法,因为它不再是字节格式。我尝试将字符串转换为字节但无济于事。任何帮助将不胜感激。
下面是输出的副本,其中加密的字节被转换为完全相同的字符串
b'\x8d\x19b\xbbE\xc1\xbf/K\x8b_}\xae\x0c\xb3\x8b\x94\x19\xfb\x8e\x01q6\xf5\xdd2O\\\xd2\xbf\xe3\xca\xcf\xac\x03\x84\xe9\xd7\xce\x13\xaaB\x16x\x13\xb4x26\xfc\x1c\xfe6\x82\xf6\x89i\x8aT\x87\xa0\xe9\x85p\xea\x03\x0fK\xb1/\xe0\x1b\x10a\x83\xa2\x0b}b\x0b\xc3\xe1"\xc1\x94\xfa\x95\xb0iQ\xa8%sqs\xc9\x98`gd,\xdc;\xa3\x08\xb6\xc3T:2N\xede-\x16\xe6i\xdc?3\x1d\x8c\x12^\x10\xde*\xc5'
<class 'bytes'>
b'\x8d\x19b\xbbE\xc1\xbf/K\x8b_}\xae\x0c\xb3\x8b\x94\x19\xfb\x8e\x01q6\xf5\xdd2O\\\xd2\xbf\xe3\xca\xcf\xac\x03\x84\xe9\xd7\xce\x13\xaaB\x16x\x13\xb4x26\xfc\x1c\xfe6\x82\xf6\x89i\x8aT\x87\xa0\xe9\x85p\xea\x03\x0fK\xb1/\xe0\x1b\x10a\x83\xa2\x0b}b\x0b\xc3\xe1"\xc1\x94\xfa\x95\xb0iQ\xa8%sqs\xc9\x98`gd,\xdc;\xa3\x08\xb6\xc3T:2N\xede-\x16\xe6i\xdc?3\x1d\x8c\x12^\x10\xde*\xc5'
<class 'str'>
False
Unable to decrypt the message.
The message signature could not be verified
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发现他是原因,修改了您的代码以使其有效(您仍然有编译错误, btw ),但是我不会在这里发布它,因为它看起来很丑陋(Code Style Wise -check [python.peps]:pep 8- python code的样式指南)感觉就像格式化整个过程。
问题是
message1 =“ {} | {}”。格式(ciphertext,signature)
弄乱了(字节)字符串,当消息被拆分时(message2 = message2 = message2。 split(“ |”)
)结果不同于 ciphertext 和签名。请注意,通过简单地 print ing变量(
print(Message2,ciphertext,signature)
)很容易发现这些东西。在我看来,更熟悉 [Python> [Python) .docs]:内置类型 - 字节对象。
可能的修复:
发送
时:
在
输出:
不用说 saparator 在两端都必须相同。
注释: pipe 字符( | ,垂直栏)似乎是一个太简单的值。如果您的一个输入字符串包含它(并且不能保证它不会),则在分开消息时,您会在接收端遇到一个大惊喜。因此,为了大大减少碰撞机会,您应该将其设置为更复杂的东西:
I found he cause, modified your code so that it works (you still have compile errors, BTW), but I'm not going to post it here as it looks ugly (code style wise - check [Python.PEPs]: PEP 8 - Style Guide for Python Code), and I don't feel like formatting the whole thing.
The problem is that
message1 = "{}|{}".format(ciphertext, signature)
messes up the (byte) strings, and when the message is split back (message2 = message2.split("|")
) the results are different from ciphertext and signature.Note that these things are easy to spot by simply printing variables (
print(message2, ciphertext, signature)
).It seems to me that it wouldn't hurt you to get more familiar with [Python.Docs]: Built-in Types - Bytes Objects.
Possible fix:
When sending
When receiving:
Output:
Needless to say that SEPARATOR needs to be the same on both ends.
Note: The pipe character(|, vertical bar) seems to be a too simple value. If one of your input strings contains it (and there's no guarantee that it wouldn't), you'll have a big surprise on the receiving end, when splitting the message. Therefore, in order to drastically reduce the collision chance, you should set it to something more complex:
这是一个正常的过程;加密后,您肯定具有不可打印的字符,甚至可能比可打印的字符更多。
为了使过程更具对称性,您应该使用字节字符串而不是纯文本和cipghertext的字符串,在python中,引导b表示,如
b“ hello”
。 (可用的加密模块还需要所有内容的字节字符串,这是加密文件的唯一方法,例如图片)。请注意, bytes 和 byte strings 之间没有区别you already have bytes, no conversion is requiredEspecially in Python 3 with its intrinsic use of unicode a look at the 编解码器单位可能会有所帮助。
This is a normal process; after encryption you have surely non-printable characters, possible even more than printable ones.
To make the process more symmetric you should use byte strings instead of strings for plain text as well as cipghertext, which in Python are indicated by a leading b as in
b"hello"
. (Available cryptography modules also require byte strings for everything, and this is the only way to encrypt files, like e.g. a picture). Note, that there is no difference between bytes and byte strings, its just a different notation, so you don't have to look for the encoding for each normal character - if you already have bytes, no conversion is requiredEspecially in Python 3 with its intrinsic use of unicode a look at the codecs unit may be helpful.