Search code examples
pythonrsadigital-signaturepycrypto

Pycrypto string too long to sign/verify


I have this code, but when I run it, it only accepts "to_address" variable of a certain lenth. When it is too long, I receive an exception:

  Traceback (most recent call last):
** IDLE Internal Exception: 
  File "C:\Python27\lib\idlelib\run.py", line 325, in runcode
    exec code in self.locals
  File "C:\Python27\lib\idlelib\run.py", line 111, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "C:\Python27\lib\Queue.py", line 176, in get
    raise Empty
Empty

This is my code:

import hashlib
import sqlite3
import socket
import time
from Crypto.PublicKey import RSA

# import keys
key_file = open('keys.pem','r')
key = RSA.importKey(key_file.read())
public_key = key.publickey()
private_key_readable = str(key.exportKey())
public_key_readable = str(key.publickey().exportKey())
address = hashlib.sha224(public_key_readable).hexdigest()

to_address = str(raw_input ("Send to address: "))
amount = str(raw_input ("How much to send: "))
timestamp = str(time.time())

transaction = str(timestamp) +":"+ str(address) +":"+ str(to_address) +":"+ str(amount)
signature = key.sign(transaction, '')
print "Client: Signature: "+str(signature)

if public_key.verify(transaction, signature) == True:
    if int(amount) < 0:
        print "Client: Signature OK, but cannot use negative amounts"

    else:
        ...process...

else:
    print "Client: Invalid signature"
    raise
#enter transaction end

If anyone knows how to go around this length limitation, it would be appreciated. Do I need to encrypt the string somehow to make it shorter in order to verify it and then decrypt it again?


Solution

  • Perhaps sign a hash of the transaction. At verification time you can take the hash again verify that.

    Regarding the signing of messages, the documentation says:

    The piece of data to sign with RSA. It may not be numerically larger than the RSA module (n).

    Watch out though. The documentation for sign and verify says:

    Attention: this function performs the plain, primitive RSA encryption (textbook). In real applications, you always need to use proper cryptographic padding, and you should not directly verify data with this method. Failure to do so may lead to security vulnerabilities. It is recommended to use modules Crypto.Signature.PKCS1_PSS or Crypto.Signature.PKCS1_v1_5 instead.

    https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html#publickey