我正在使用pycrypto模块在python中复制TCP客户端 - 服务器安全握手。当"服务器"通过套接字发送公钥,我被迫将公钥转换为字符串。 "客户"然后接收公钥作为字符串,不能根据pycrypto
模块加密。
我收到错误:
属性错误:' str'对象在客户端没有引用 enc_data = public_key.encrypt(secret_piece,12)的属性' 。
如何将字符串public_key
转换回RSA模块首次生成时的原始值?
服务器代码:
def main():
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(1)
c, addr = s.accept()
print "Connection from: "+str(addr)
while True:
data = c.recv(1024)
if not data:
break
print "from connected user: "+str(data)
print "Start the SSL Handshake..."
a = raw_input('Press enter to generate the key pair. ')
key = RSA.generate(1024, random_generator)
public_key = key.publickey()
print "Key pair generated"
a = raw_input('Press enter to send public key to client ')
print "Sending key..."
if c.send(str(public_key)):
print "Public Key Sent"
print "Waiting for secret list..."
if c.recv(1024):
print "List received."
secret_list = c.recv(1024)
a = raw_input('Press enter to check the information from the list. ')
decrypted_info = key.decrypt(secret_list.enc_data)
match_or_not = SHA256.new(decrypted_info).digest() == secret_list.hash_value
if match_or_not:
print "Info Matches. Sending the ciphertext..."
info_to_be_encrypted = "It seems all secure. Let's talk!"
aes = AES.new(Random.get_random_bytes(16), AES.MODE_ECB)
cipher_text = aes.encrypt(info_to_be_encrypted)
if c.send(cipher_text):
print "Ciphertext sent."
客户代码
def main():
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.connect((host,port))
message = raw_input("-> ")
while message != 'q':
s.send(message)
public_key = s.recv(1024)
print 'Received from server: '+str(public_key)
message = raw_input("->Press enter to verify the public key.")
print "Public Key verified!"
message = raw_input("-> Press enter to prepare the secret list.")
print "Client prepares the secret list."
secret_piece = Random.get_random_bytes(16)
enc_data = public_key.encrypt(secret_piece, 12)
hash_value = SHA256.new(secret_piece).digest()
L = [enc_data, hash_value]
print "List is ready."
message = raw_input("-> Press enter to send the list")
s.send(str(L))
print "List sent."
print "Waiting for ciphertext from the server..."
if s.recv(1024):
print "Ciphertext recieved."
cipher_text = s.recv(1024)
print "The encrypted message is: " + cipher_text
print "The decrypted message is: " + aes.decrypt(cipher_text)
s.close()
答案 0 :(得分:0)
解决方案:使用exportKey()
和importKey()
为什么您的转化不起作用
使用str()
将密钥转换为字符串不起作用,您可以从下面的示例中看到。
>>> k = RSA.generate(1024)
>>> pk = k.publickey()
>>> str(pk)
'<_RSAobj @0x10e518908 n(1024),e>'
从上面的示例中可以看出,函数str()
只返回不显示实际密钥的字符串'<_RSAobj @0x10e518908 n(1024),e>'
。
将关键对象转换为字符串
将密钥转换为字符串的好方法是使用标准格式导出密钥,例如众所周知的PEM格式,如下所示。
>>> pkstring = pk.exportKey("PEM")
>>> pkstring
'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4SD0YSMWYAU27mFVKsHgtKWzM\n9jfvs2Xl+zCQpAHNtvYWTo6mnyWTwH4lGn7ulYdGx5gAJj6OlWg+CKoHXqPOh6e4\nP8DM97dM9QfP8d7el2ZCz1+5oMd8iQo+WPTM1qa5TMj9rZMpwAnSrS490LW6ZpTL\n7fChg3APljnspQ/7nQIDAQAB\n-----END PUBLIC KEY-----'
现在,pk.exportKey("PEM")
返回的字符串对应于实际键。
将字符串转换回关键对象
这也很简单,你只需输入:
>>> importedpk = RSA.importKey(pkstring)
现在,您可以将encrypt
方法与已使用字符串importedpk
转换的pkstring
密钥一起使用。
为了证明您已正确加载importedpk
,只需在python解释器上键入以下两个命令。
pk.encrypt("Hello", 12)
importedpk.encrypt("Hello", 12)
他们应该返回相同的输出。特别是,如果你输入
pk.encrypt("Hello", 12) == importedpk.encrypt("Hello", 12)
结果应该是
True
如何修复代码
在服务器代码中,替换
if c.send(str(public_key)):
print "Public Key Sent"
与
if c.send(public_key.exportKey("PEM")):
print "Public Key Sent"
在客户端代码中,替换
public_key = s.recv(1024)
与
public_key = RSA.importKey(s.recv(1024))
答案 1 :(得分:0)
我通过使用public_key
模块aka cpickle
来挑选pickle.dumps(public_key)
对象来解决此问题。腌制物体可以通过插座移动并被另一侧的客户“打开”!