Sample code for 30+ languages & platforms
Xbase++

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 Xbase++ Downloads

Xbase++
LOCAL nSuccess
LOCAL oCrypt
LOCAL cHashStr
LOCAL oDsa
LOCAL cPemPrivateKey
LOCAL cAsnSig
LOCAL oAsn
LOCAL oXml
LOCAL r
LOCAL s
LOCAL oDsa2
LOCAL cPemPublicKey

nSuccess := 0

//  This example requires the Chilkat API to have been previously unlocked.
//  See Global Unlock Sample for sample code.

oCrypt := CreateObject("Chilkat.Crypt2")

oCrypt:EncodingMode := "hex"
oCrypt:HashAlgorithm := "sha-1"

cHashStr := oCrypt:HashFileENC("qa_data/hamlet.xml")
? "hash to sign: " + cHashStr

oDsa := CreateObject("Chilkat.Dsa")

cPemPrivateKey := oDsa:LoadText("qa_data/dsa/dsaPrivKey2.pem")
nSuccess := oDsa:FromPem(cPemPrivateKey)
IF (nSuccess == 0)
    ? oDsa:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    RETURN
ENDIF

//  Load the hash to be signed into the DSA object:
nSuccess := oDsa:SetEncodedHash("hex", cHashStr)
IF (nSuccess == 0)
    ? oDsa:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    RETURN
ENDIF

//  Sign the hash.
nSuccess := oDsa:SignHash()
IF (nSuccess == 0)
    ? oDsa:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    RETURN
ENDIF

//  Get the ASN.1 signature.
cAsnSig := oDsa:GetEncodedSignature("base64")
? "Signature: " + cAsnSig

//  Examine the details of the ASN.1 signature.
//  We want to get the r,s values as hex strings..
oAsn := CreateObject("Chilkat.Asn")
nSuccess := oAsn:LoadEncoded(cAsnSig, "base64")
IF (nSuccess == 0)
    ? oAsn:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    oAsn:destroy()
    RETURN
ENDIF

//  Get the ASN.1 as XML.
oXml := CreateObject("Chilkat.Xml")
nSuccess := oXml:LoadXml(oAsn:AsnToXml())
? "Signature as XML: "
? oXml:GetXml()

//  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 := "2C187F3AB6E47A66497B86CE97BB39E2133810F5"
s := "588E53D3F7B69636B48FD7175E99A3961BD7D775"

//  Build the XML that will be converted to ASN.1
oXml:Clear()
oXml:Tag := "sequence"
oXml:NewChild2("int", r)
oXml:NewChild2("int", s)

//  Convert the XML to ASN.1
nSuccess := oAsn:LoadAsnXml(oXml:GetXml())

//  Emit the signature as DER encoded ASN.1 (base64)
cAsnSig := oAsn:GetEncodedDer("base64")

//  --------------------------------------------------------------------
//  Verify the signature using the asnSig we built from the r,s values
//  --------------------------------------------------------------------

oDsa2 := CreateObject("Chilkat.Dsa")

//  Load the DSA public key to be used for verification:

cPemPublicKey := oDsa2:LoadText("qa_data/dsa/dsaPubKey2.pem")
nSuccess := oDsa2:FromPublicPem(cPemPublicKey)
IF (nSuccess == 0)
    ? oDsa2:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    oAsn:destroy()
    oXml:destroy()
    oDsa2:destroy()
    RETURN
ENDIF

//  Load the hash to be verified.
nSuccess := oDsa2:SetEncodedHash("hex", cHashStr)
IF (nSuccess == 0)
    ? oDsa2:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    oAsn:destroy()
    oXml:destroy()
    oDsa2:destroy()
    RETURN
ENDIF

//  Load the ASN.1 signature:
nSuccess := oDsa2:SetEncodedSignature("base64", cAsnSig)
IF (nSuccess == 0)
    ? oDsa2:LastErrorText
    oCrypt:destroy()
    oDsa:destroy()
    oAsn:destroy()
    oXml:destroy()
    oDsa2:destroy()
    RETURN
ENDIF

//  Verify:
nSuccess := oDsa2:Verify()
IF (nSuccess == 0)
    ? oDsa2:LastErrorText
ELSE
    ? "DSA Signature Verified!"
ENDIF

oCrypt:destroy()
oDsa:destroy()
oAsn:destroy()
oXml:destroy()
oDsa2:destroy()