gpt4 book ai didi

python - PyCryptodome RSA 签名和验证

转载 作者:太空宇宙 更新时间:2023-11-04 00:22:37 37 4
gpt4 key购买 nike

我正在开发一个程序,该程序使用 socket 模块在 python 中通过互联网传输数据。我现在正在尝试使用 pycryptodome 模块实现加密。我正在使用 Salsa20 传输普通消息并传输我正在使用 RSA 的 Salsa20 key 。问题是代码在验证散列时引发了 ValueError。这是协议(protocol):

  1. 客户端连接到服务器(并生成 Salsa20 key )
  2. 服务器生成一对RSA key ,并将公钥发送给客户端
  3. 客户端生成自己的 key 对并发送公钥
  4. 客户端用公钥加密Salsa20 key
  5. 客户端签名并发送加密的 Salsa20 key 的哈希值
  6. 客户端发送加密的Salsa20 key
  7. 服务器对未签名的加密 key 进行哈希处理,并验证它与已签名的 key 相同(这是出现问题的行)
  8. 服务器解密未签名的 key

我反复检查打印,hash都是一样的。 socket 不是问题。

recv_message 和 send_message 函数是我用来打包发送和接收协议(protocol)的函数。在程序中,套接字是预先设置好的,所以这里是服务器的重要部分。

import socket
from Crypto.Cipher import Salsa20, PKCS1_OAEP
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA

def send_message(message_to_send, connection):
if type(message_to_send) is bytes:
message = message_to_send
else:
message = str(message_to_send).encode()
length_of_msg = str(len(message))
length_of_msg = ('0' * (5-len(length_of_msg))) + length_of_msg # This part is adding zeros as padding so that the first message is always 5 chars
connection.send(length_of_msg.encode())
connection.send(message)

def recv_message(connection, no_decode=False):
length_of_msg = int(connection.recv(5))
message = connection.recv(length_of_msg)
if not no_decode:
message = message.decode('utf-8')
return message

def get_key(connection):
rsa_server_key = RSA.generate(2048)
send_message(rsa_server_key.publickey().exportKey(), connection)
rsa_client_key = RSA.import_key(recv_message(connection, no_decode=True))
key_signed = recv_message(connection, no_decode=True)
key_unsigned = recv_message(connection, no_decode=True)
hash_verify = pkcs1_15.new(rsa_client_key)
hash_verify.verify(SHA256.new(data=key_unsigned), key_signed)
rsa_cipher = PKCS1_OAEP.new(rsa_server_key)
key = rsa_cipher.decrypt(key_unsigned)
return key

客户端具有相同的套接字相关功能和导入模块。

def share_key(key_to_send, connection):
rsa_server_key = RSA.import_key(recv_message(connection, no_decode=True))
rsa_client_key = RSA.generate(2048)
send_message(rsa_server_key.publickey().exportKey(), connection)
rsa_cipher = PKCS1_OAEP.new(rsa_server_key)
salsa_key_unsigned = rsa_cipher.encrypt(key_to_send)
key_signer = pkcs1_15.new(rsa_client_key)
send_message(key_signer.sign(SHA256.new(data=salsa_key_unsigned)), connection)
send_message(salsa_key_unsigned, connection)

回溯是:

Traceback (most recent call last):
File "0,9Serverside.py", line 686, in <module>
main()
File "0,9Serverside.py", line 670, in main
key_input = get_key(server)
File "0,9Serverside.py", line 243, in get_key
hash_verify.verify(SHA256.new(data=salsa_key_unsigned), salsa_key_signature)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/Crypto/Signature/pkcs1_15.py", line 139, in verify
raise ValueError("Invalid signature")
ValueError: Invalid signature

您认为验证无效的原因可能是什么。感谢您的帮助。

最佳答案

客户端发回服务器的公钥而不是自己的公钥。线路:

 send_message(rsa_server_key.publickey().exportKey(), connection)

应该是:

 send_message(rsa_client_key.publickey().exportKey(), connection)

关于python - PyCryptodome RSA 签名和验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48601182/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com