Thursday, January 21, 2021

Using ECDSA in Python to Sign and Verify messages

  





In this post we will review how to sign and verify messages in GO using ECDSA. This is an asymmetric encryption mechanism that is based on elliptic curve cryptography.

First, lets generate a private key.


from hashlib import sha256

from ecdsa import SigningKey, SECP256k1, VerifyingKey
from ecdsa.ellipticcurve import Point

private_key = SigningKey.generate(curve=SECP256k1)


The private key is based on a secret. This secret can be exported if we want to later import reload the same private key.


exported_secret = private_key.to_string()
private_key = SigningKey.from_string(exported_secret, curve=SECP256k1)


From the private key, we can deduce the public key. The public key is used for verification of the signature, and as its name implied, is public, so we should send to the party that needs to verify the sender identity. The public key can be send using the X,Y variables, and imported on the other party side.



public_key = private_key.get_verifying_key()
point = Point(SECP256k1.curve, public_key.pubkey.point.x(), public_key.pubkey.point.y())
public_key_imported = VerifyingKey.from_public_point(point, curve=SECP256k1)



Once we have a private key (generated or imported) we can sign messages. First we hash the message using sha256, and then we sign the hash. The result of the signature is two variables: R,S. These should be sent as additional metadata for authentication of the message sender identify (as well as the public key that we have already sent). 


message = b'hello'
signature = private_key.sign(message, sigencode=my_signature_encode, hashfunc=sha256)
print("R", signature[0])
print("S", signature[1])


To verify the message we use the public key.



def my_signature_decode(signature, order):
return signature[0], signature[1]


verify = public_key.verify(signature, message, sigdecode=my_signature_decode, hashfunc=sha256)
print("verify", verify)




1 comment: