I am trying to make my blockchain model using pycryptodome 3.16.0, but can't understand how to sign and verify a blockchain transaction. As far as I understand first client (f.e. John) sign transaction using his private key. The second client (f.e. Edgar) use his public key to verify transaction. I define my class Client:
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from binascii import hexlify
class Client:
def __init__(self):
random = Crypto.Random.new().read
self._private_key = RSA.generate(2048, random)
self._public_key = self._private_key.publickey()
self._signer = PKCS1_v1_5.new(self._private_key)
@property
def identity(self):
return hexlify(self._public_key.exportKey(format='DER')).decode('ascii')
@property
def public_key(self):
return self._public_key
and class Transaction:
import datetime
import collections
import binascii
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
class Transaction:
def __init__(self, sender, recipient, value):
self._sender = sender
self._recipient = recipient
self._value = value
self._time = datetime.datetime.now()
self._signature = None
self._hash = None
def sign_transaction(self):
private_key = self._sender._private_key
signer = PKCS1_v1_5.new(private_key)
h = SHA256.new()
self._hash = h
self._signature = signer.sign(h)
def validate_transaction(self):
public_key = self._recipient._public_key
signer = PKCS1_v1_5.new(public_key)
return signer.verify(self._hash, self._signature)
So, when i try to sign and verify my transaction it returns False always when signers in sign_transaction and validate_transaction are not the similiar (change _recipient to _sender in validate_transaction or _sender to _recipient in sign_transaction and it returns True regardless of which key to use for signing and verification):
import client
import transaction
t0 = transaction.Transaction(John, Edgar, 100)
t0.sign_transaction()
t0.validate_transaction() # False
I expected that verification would return True when using the following key pairs:
- sender private key - recipient public key
- sender private key - sender public key (sender can verify his own transaction for himself)
Also i tried to use answers from similiar question (Signing and verifying data using pycrypto (RSA)), but now public_key.sign from Crypto.PublicKey.RSA returns NotImplementedError("Use module Crypto.Signature.pkcs1_15 instead")