I am trying to have a program sign and then later verify the contents of a file. However, wile the first verification will always return true, once the data is written to files and then loaded again, the verification usually fails, but is sometimes successful.
Even when the code fails, The outputs of the two print signature
and print hash.hexdigest()
calls are visually identical.
My test code is:
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_PSS
def generate():
key_file = open("TestPrivateKey")
private_key = RSA.importKey(key_file)
public_key = private_key.publickey()
seed_file = open("Seed")
plaintext = seed_file.read()
hash = SHA256.new(plaintext)
signer = PKCS1_PSS.new(private_key)
signature = signer.sign(hash)
plaintext_file = open("plaintext", 'w')
plaintext_file.write(plaintext)
signature_file = open("signature", 'w')
signature_file.write(signature)
print signature
print hash.hexdigest()
verifier = PKCS1_PSS.new(public_key)
print verifier.verify(hash, signature)
def verification_test():
plaintext_file = open("plaintext")
signature_file = open("signature", 'rb')
plaintext = plaintext_file.read()
public_key = RSA.importKey(open("TestPublicKey"))
signature = signature_file.read()
print signature
hash = SHA256.new(plaintext)
print hash.hexdigest()
verifier = PKCS1_PSS.new(public_key)
return verifier.verify(hash, signature)
if __name__ == '__main__':
generate()
print verification_test()
Does anyone know what mistake I made? There must be something happening when the signature is written to the file and then read back in, but I can't figure out what it is.
Edit: Before I run this script, I run the initialization functions:
from Crypto.PublicKey import RSA
def create_keys():
private_key = RSA.generate(4096)
file = open("TestPrivateKey", 'w')
file.write(private_key.exportKey())
file = open("TestPublicKey", 'w')
file.write(private_key.publickey().exportKey())
def create_seed():
file = open("Seed", 'w')
file.write("Test")
I notice two problems with your code.
First, you are writing arbitrary binary data to a file what was opened for text:
signature_file = open("signature", 'w') #bad
signature_file.write(signature)
should be:
signature_file = open("signature", 'wb') #good
signature_file.write(signature)
Second, you never close your files. Try this:
with open("signature", 'wb') as signature_file:
signature_file.write(signature)
and similarly for all of the other open files.
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_PSS
def generate():
with open("TestPrivateKey") as key_file:
private_key = RSA.importKey(key_file)
public_key = private_key.publickey()
with open("Seed") as seed_file:
plaintext = seed_file.read()
hash = SHA256.new(plaintext)
signer = PKCS1_PSS.new(private_key)
signature = signer.sign(hash)
with open("plaintext", 'w') as plaintext_file:
plaintext_file.write(plaintext)
with open("signature", 'wb') as signature_file:
signature_file.write(signature)
#print signature
print hash.hexdigest()
verifier = PKCS1_PSS.new(public_key)
print verifier.verify(hash, signature)
def verification_test():
with open("plaintext") as plaintext_file:
plaintext = plaintext_file.read()
with open("signature", 'rb') as signature_file:
signature = signature_file.read()
with open("TestPublicKey") as public_key_file:
public_key = RSA.importKey(public_key_file)
#print signature
hash = SHA256.new(plaintext)
print hash.hexdigest()
verifier = PKCS1_PSS.new(public_key)
return verifier.verify(hash, signature)
if __name__ == '__main__':
generate()
print verification_test()