2015-05-07 52 views
1

使用套接字创建了一个客户端 - 服务器应用程序,我试图将签名从客户端传输到服务器。我将它从元组转换为字符串,然后返回到元组。但签署停止工作。如何解决这个问题?PyCrypto导出/导入签名

from Crypto.Hash import SHA256 
from Crypto.PublicKey import RSA 

public_key_file = open('public.pem','r') 
public_key = RSA.importKey(public_key_file.read()) 

signature = "(90392831408741910958006452852395405116864328891950288888434929210668328849466319419951775157374761930395371626801844365799774616689823184955256615103504859356914334395152128600862146719619859327119380994333493461955529620578485576675021993313219918726432622856542420570716350341841652548574072964446809201965L,)" 
signature_tuple = signature.split(",") 
message = "Block_Height:1 From:c52030257a864a67ae4ef8a726282ed2b6b273fbccb474885027a857 To:2 Amount:3" 

if public_key.verify(message, signature_tuple) == True: 
    print "Signature valid" 

Traceback (most recent call last): 
    File "C:\Users\kucerjan\Desktop\test\sco\public_test.py", line 12, in <module> 
    if public_key.verify(message, signature_tuple) == True: 
    File "build\bdist.win32\egg\Crypto\PublicKey\RSA.py", line 221, in verify 
    return pubkey.pubkey.verify(self, M, signature) 
    File "build\bdist.win32\egg\Crypto\PublicKey\pubkey.py", line 126, in verify 
    return self._verify(M, signature) 
    File "build\bdist.win32\egg\Crypto\PublicKey\RSA.py", line 257, in _verify 
    return self.key._verify(m, s) 
    File "build\bdist.win32\egg\Crypto\PublicKey\_slowmath.py", line 73, in _verify 
    return self._encrypt(sig) == m 
    File "build\bdist.win32\egg\Crypto\PublicKey\_slowmath.py", line 65, in _encrypt 
    return pow(m, self.e, self.n) 
TypeError: unsupported operand type(s) for pow(): 'str', 'long', 'long' 

此签名已使用str(签名)转换为字符串。我基本上需要将其转换为字符串并返回。

功能参考:https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html#verify

公钥:

-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFiMH7Lbd4JPFug8TaxX1DT8ad 
lzzGm7CG1js0IQn2pCPPWBS+io1i0iUPmj78IOtUuoBqtEYGPgwqguYHozBuvdJy 
Lcz4C2bYcjb2l8mQ4PM7iaCN4eHB+4xa+iJduogTjq8gx5m3j5mttEGUbZc2Q/AO 
yde592P2iuRIrXcLuwIDAQAB 
-----END PUBLIC KEY----- 

回答

3

的问题是在反序列化签名元组。

PyCrypto期待着与一个整数作为第一值的元组,你是一个开始括号“(”,然后一个数字的字符串版本传递一个字符串

而不是做这个的。

signature_tuple = signature.split(",") 

做到这一点

signature_tuple = eval(signature) 

这将正确解析签名。

现在,有security risks with using eval。所以,如果我是你,我会想出一个更好的序列化/反序列化过程。

+0

非常感谢,这工作!我只是从这个开始,所以在完成一些测试阶段后,我会考虑一个更好的过程。 – HCLivess

+0

现在我想在评估之前使用类似正则表达式检查的东西: 'match = re.match(“\(\ d + L \,\)”,签名) if match!= None: signature_tuple = eval(签名) else: print“收到恶意代码”' – HCLivess

+0

好吧,我会使用'signature_tuple = ast.literal_eval(签名)',我应该是安全的。谢谢,不知道eval是那种邪恶。 – HCLivess

1

最好的方法是将PKCS1_v1_5用于真正的应用程序与base64的组合,以便对客户端和服务器之间的签名进行编码和解码。不需要评估。

from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import SHA 
from Crypto.PublicKey import RSA 
import base64 

message = 'To be signed' 
key = RSA.importKey(open('privkey.der').read()) 
h = SHA.new(message) 
signer = PKCS1_v1_5.new(key) 
signature = signer.sign(h) 
signature_enc = str(base64.b64encode(signature)) 
#print signature_enc 


signature_dec = str(base64.b64decode (signature_enc)) 
#print sugnature_dec 
key = RSA.importKey(open('pubkey.der').read()) 
h = SHA.new(message) 
verifier = PKCS1_v1_5.new(key) 
if verifier.verify(h, signature_dec): 
    print "The signature is authentic." 
else: 
    print "The signature is not authentic."