如何将密钥字符串转换回 pycrypto 密钥对象? (Python)

问题描述 投票:0回答:2

我正在使用 pycrypto 模块在 python 中复制 TCP 客户端-服务器安全握手。当“服务器”通过套接字发送公钥时,我被迫将公钥转换为字符串。然后,“客户端”接收字符串形式的公钥,该字符串无法根据

pycrypto
模块进行加密。

我收到错误:

AttributeError:'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()
python string client-server pycrypto
2个回答
0
投票

解决方案: 使用

exportKey()
importKey()

导出/导入密钥

为什么您的转换不起作用

使用

str()
将密钥转换为字符串不起作用,如下面的示例所示。

>>> k = RSA.generate(1024)
>>> pk = k.publickey()
>>> str(pk)
'<_RSAobj @0x10e518908 n(1024),e>'

从上面的示例中可以看到,函数

str()
仅返回字符串
'<_RSAobj @0x10e518908 n(1024),e>'
,它不显示实际的键。

将key对象转换为字符串

将密钥转换为字符串的一个好方法是使用标准格式导出它,例如众所周知的 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")
返回的字符串对应于actual键。

将字符串转换回关键对象

这也很简单,你只需输入:

>>> 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))

0
投票

我通过使用

public_key
模块(又名
cpickle
)酸洗
pickle.dumps(public_key)
对象解决了这个问题。 pickled 对象能够通过套接字传输并被另一端的客户端“unpickled”!

© www.soinside.com 2019 - 2024. All rights reserved.