PureBasic
PureBasic
DSA R,S Signature Values
See more DSA Examples
Creates a DSA signature. Gets r,s values from the signature. Re-creates the DSA signature ASN.1 from the r,s values. Then verifies the signature using the re-created ASN.1 DSA signature.Chilkat PureBasic Downloads
IncludeFile "CkXml.pb"
IncludeFile "CkDsa.pb"
IncludeFile "CkAsn.pb"
IncludeFile "CkCrypt2.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
crypt.i = CkCrypt2::ckCreate()
If crypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCrypt2::setCkEncodingMode(crypt, "hex")
CkCrypt2::setCkHashAlgorithm(crypt, "sha-1")
hashStr.s = CkCrypt2::ckHashFileENC(crypt,"qa_data/hamlet.xml")
Debug "hash to sign: " + hashStr
dsa.i = CkDsa::ckCreate()
If dsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
pemPrivateKey.s
pemPrivateKey = CkDsa::ckLoadText(dsa,"qa_data/dsa/dsaPrivKey2.pem")
success = CkDsa::ckFromPem(dsa,pemPrivateKey)
If success = 0
Debug CkDsa::ckLastErrorText(dsa)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
ProcedureReturn
EndIf
; Load the hash to be signed into the DSA object:
success = CkDsa::ckSetEncodedHash(dsa,"hex",hashStr)
If success = 0
Debug CkDsa::ckLastErrorText(dsa)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
ProcedureReturn
EndIf
; Sign the hash.
success = CkDsa::ckSignHash(dsa)
If success = 0
Debug CkDsa::ckLastErrorText(dsa)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
ProcedureReturn
EndIf
; Get the ASN.1 signature.
asnSig.s = CkDsa::ckGetEncodedSignature(dsa,"base64")
Debug "Signature: " + asnSig
; Examine the details of the ASN.1 signature.
; We want to get the r,s values as hex strings..
asn.i = CkAsn::ckCreate()
If asn.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkAsn::ckLoadEncoded(asn,asnSig,"base64")
If success = 0
Debug CkAsn::ckLastErrorText(asn)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
CkAsn::ckDispose(asn)
ProcedureReturn
EndIf
; Get the ASN.1 as XML.
xml.i = CkXml::ckCreate()
If xml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXml::ckLoadXml(xml,CkAsn::ckAsnToXml(asn))
Debug "Signature as XML: "
Debug CkXml::ckGetXml(xml)
; Sample XML shown here.
; The r and s values are the two hex strings in the XML.
; <?xml version="1.0" encoding="utf-8"?>
; <sequence>
; <int>2C187F3AB6E47A66497B86CE97BB39E2133810F5</int>
; <int>588E53D3F7B69636B48FD7175E99A3961BD7D775</int>
; </sequence>
; Pretend we're starting with r,s
r.s = "2C187F3AB6E47A66497B86CE97BB39E2133810F5"
s.s = "588E53D3F7B69636B48FD7175E99A3961BD7D775"
; Build the XML that will be converted to ASN.1
CkXml::ckClear(xml)
CkXml::setCkTag(xml, "sequence")
CkXml::ckNewChild2(xml,"int",r)
CkXml::ckNewChild2(xml,"int",s)
; Convert the XML to ASN.1
success = CkAsn::ckLoadAsnXml(asn,CkXml::ckGetXml(xml))
; Emit the signature as DER encoded ASN.1 (base64)
asnSig = CkAsn::ckGetEncodedDer(asn,"base64")
; --------------------------------------------------------------------
; Verify the signature using the asnSig we built from the r,s values
; --------------------------------------------------------------------
dsa2.i = CkDsa::ckCreate()
If dsa2.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Load the DSA public key to be used for verification:
pemPublicKey.s
pemPublicKey = CkDsa::ckLoadText(dsa2,"qa_data/dsa/dsaPubKey2.pem")
success = CkDsa::ckFromPublicPem(dsa2,pemPublicKey)
If success = 0
Debug CkDsa::ckLastErrorText(dsa2)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
CkAsn::ckDispose(asn)
CkXml::ckDispose(xml)
CkDsa::ckDispose(dsa2)
ProcedureReturn
EndIf
; Load the hash to be verified.
success = CkDsa::ckSetEncodedHash(dsa2,"hex",hashStr)
If success = 0
Debug CkDsa::ckLastErrorText(dsa2)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
CkAsn::ckDispose(asn)
CkXml::ckDispose(xml)
CkDsa::ckDispose(dsa2)
ProcedureReturn
EndIf
; Load the ASN.1 signature:
success = CkDsa::ckSetEncodedSignature(dsa2,"base64",asnSig)
If success = 0
Debug CkDsa::ckLastErrorText(dsa2)
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
CkAsn::ckDispose(asn)
CkXml::ckDispose(xml)
CkDsa::ckDispose(dsa2)
ProcedureReturn
EndIf
; Verify:
success = CkDsa::ckVerify(dsa2)
If success = 0
Debug CkDsa::ckLastErrorText(dsa2)
Else
Debug "DSA Signature Verified!"
EndIf
CkCrypt2::ckDispose(crypt)
CkDsa::ckDispose(dsa)
CkAsn::ckDispose(asn)
CkXml::ckDispose(xml)
CkDsa::ckDispose(dsa2)
ProcedureReturn
EndProcedure