Chilkat2-Python
Chilkat2-Python
ECDSA Sign and Verify
See more ECC Examples
Demonstrates how to create an ECDSA signature on the SHA256 hash of some data, and then verify.Chilkat Chilkat2-Python Downloads
import sys
import chilkat2
success = False
# This example assumes the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.
# First load an ECDSA private key to be used for signing.
privKey = chilkat2.PrivateKey()
success = privKey.LoadEncryptedPemFile("qa_data/ecc/secp256r1-key-pkcs8-secret.pem","secret")
if (success == False):
print(privKey.LastErrorText)
sys.exit()
# Sign the SHA256 hash of some data.
bd = chilkat2.BinData()
success = bd.LoadFile("qa_data/hamlet.xml")
if (success == False):
print("Failed to load file to be hashed.")
sys.exit()
crypt = chilkat2.Crypt2()
crypt.HashAlgorithm = "sha256"
crypt.EncodingMode = "base64"
hashStr = crypt.HashBdENC(bd)
ecdsa = chilkat2.Ecc()
prng = chilkat2.Prng()
# Returns ASN.1 signature as a base64 string.
sig = ecdsa.SignHashENC(hashStr,"base64",privKey,prng)
print("sig = " + sig)
# The signature is in ASN.1 format (which may be described as the "encoded DSS signature").
# SEQUENCE (2 elem)
# INTEGER (255 bit) 4849395540832462044300553275435608522154141569743642905628579547100940...
# INTEGER (255 bit) 3680701124244788134409868118208591399799457104230118295614152238560005...
# If you wish, you can get the r and s components of the signature like this:
asn = chilkat2.Asn()
asn.LoadEncoded(sig,"base64")
xml = chilkat2.Xml()
xml.LoadXml(asn.AsnToXml())
print(xml.GetXml())
# We now have this:
# <?xml version="1.0" encoding="utf-8"?>
# <sequence>
# <int>6650D422D86BA4A228B5617604E59052591B9B2C32EF324C44D09EF67E5F0060</int>
# <int>0CFD9F6AC85042FC70F672C141BA6B2A4CAFBB906C3D907BCCC1BED62B28326F</int>
# </sequence>
# Get the "r" and "s" as hex strings
r = xml.GetChildContentByIndex(0)
s = xml.GetChildContentByIndex(1)
print("r = " + r)
print("s = " + s)
# --------------------------------------------------------------------
# Now verify against the hash of the original data.
# Get the corresponding public key.
pubKey = chilkat2.PublicKey()
success = pubKey.LoadFromFile("qa_data/ecc/secp256r1-pub.pem")
if (success == False):
print(pubKey.LastErrorText)
sys.exit()
# We already have the SHA256 hash of the original data (hashStr) so no need to re-do it..
ecc2 = chilkat2.Ecc()
result = ecc2.VerifyHashENC(hashStr,sig,"base64",pubKey)
if (result != 1):
print(ecc2.LastErrorText)
sys.exit()
print("Verified!")
# Note: If we have only r,s and wish to reconstruct the ASN.1 signature, we do it like this:
xml2 = chilkat2.Xml()
xml2.Tag = "sequence"
xml2.NewChild2("int",r)
xml2.NewChild2("int",s)
asn2 = chilkat2.Asn()
asn2.LoadAsnXml(xml2.GetXml())
encodedSig = asn2.GetEncodedDer("base64")
print("encoded DSS signature: " + encodedSig)
# You can go to https://lapo.it/asn1js/ and copy/paste the base64 encodedSig into the online tool, then press the "decode" button.
# You will see the ASN.1 such as this:
# SEQUENCE (2 elem)
# INTEGER (255 bit) 4849395540832462044300553275435608522154141569743642905628579547100940...
# INTEGER (255 bit) 3680701124244788134409868118208591399799457104230118295614152238560005...