Topic: Transmission of DSA signature

Hello,

After computing the DSA signature, I get a 40 bytes buffer with the integers r and s.
I am appending this to the data I want to sign and then sending the whole packet to its destination.

The problem is that the server I am using requires the DSA signatue to be DER encoded according to
section 2.2.2 of RFC3279, so obviously the signature verification fails.

Is there already some functionality in wolfCrypt to do this, or do I need to implement it myself ?

Also, on the manual at the end of section 10.5.4, it seems that the original private key is used to verify the signature.
Is this correct, or the key argument is implicitly assumed to be the public key counterpart ?

Share

Re: Transmission of DSA signature

Hi @nelsongoncalves,

Can you clarify what protocol you are working with? Why are you (for example) computing an R and S and manually building a packet then shipping that to a peer where the verification is failing. What protocol is this, what kind of packet is this, what protocol is the peer using?

Let's start with a bit of background on the effort so we can better understand what it is you are attempting to solve.

Warm Regards,

K

Re: Transmission of DSA signature

Hello Kaleb,

There is no protocol, I am just using wolfSSL in a proof of concept where the DSA algorithm is used to sign messages.
The steps I am making are:

0. a public/private key pair is generated, the client has the private key while the server has the public counterpart
    I performed this step using openssl, then exported both keys to DER encoded files

openssl dsaparam -out dsaparam.pem 1024
openssl gendsa -out dsa.pem dsaparam.pem
openssl dsa -in dsa.pem -outform DER -pubout -out dsa_public.der
openssl dsa -in dsa.pem -outform DER -out dsa_private.der

1. a message (= octect string) is generated at the client side and signed with the private key:

// this code is based on section 10.5.4 of the wolfSSL manual, error handling is not shown for brevity

DsaKey  privKey;
RNG      rng;
uint8_t   signature[40] = { 0x00 };
uint8_t   shaDigest[SHA256_DIGEST_SIZE] = { 0x00 };
uint32_t  idx = 0;

// initialize random number generator and DSA private key structure
wc_InitDsaKey(&privKey);  
wc_InitRng(&rng);    
 
// load the key, assumed to be in ASN.1 DER encoding
// pKey is a uint8_t buffer with the contents of the file dsa_private.der
// keySize is the length of the pKey buffer
wc_DsaPrivateKeyDecode(pKey, &idx, &privKey, keySize);  

 // hash the message (also done using wolfCrypt functions, but not show for brevity)
// message is an uint8_t buffer, with size messageSize
// I verified the hash and it is correct
compute_sha256(shaDigest,message, messageSize);  

// compute the signature
wc_DsaSign(shaDigest,signature,&privKey, &rng);    

// free used resources
wc_FreeDsaKey(&privKey);
wc_FreeRng(&rng);

2. append the signature to the end of the message, message = message || signature
   This is done by simply writing both to a file.

3. send it to the server and verify its signature
   In this proof of concept, it is just a Python program that reads the public key and the file with: message || signature
   I am using the Python library cryptography https://cryptography.io/en/latest/

The signature verification fails (step 3), because the Python library expects the signature to be encoded per RFC 3279 (https://cryptography.io/en/latest/hazma … a/#signing), instead of being the concatenation of R and S.

It is very much possible that I am not correctly using the wolfCrypt library or that I am using the DSA algorithm in the wrong manner. But I cannot understand what it is.

Share

Re: Transmission of DSA signature

nelsongoncalves,

Can you try calling wc_EncodeSignature before doing the "sign" operation (like in this example https://github.com/wolfSSL/wolfssl-exam … st.c#L165) and let me know if that addresses the expected format issue?

Example:

   /* Add ASN digest info header */
   ret = wc_EncodeSignature(Digest_buf, Hash_buf, Hash_len, SHAh);
   printf("Digest Header: %d\n", ret);
   if (ret <= 0) { error handling };
   Digest_len = ret;

Warm Regards,

K

Re: Transmission of DSA signature

Hello Kaleb,

Unfortunately it did not work.
Also, it is not clear to me why the signature should be encoded *before* it is computed.
Am I understanding this wrong, or in the example you provided it is the hash of the message that is being encoded ?

Share

Re: Transmission of DSA signature

In the sample I provided it is the "hash" that is being encoded with ASN formatting before the signature is generated. Since RSA sign is basically an "encrypt" due to the nature of RSA you put the ASN encoding on the hash before doing the sign operation.


You mentioned: "The signature verification fails (step 3), because the Python library expects the signature to be encoded per RFC 3279 "

Perhaps try calling wc_EncodeSignature after the signature since you're using DSA instead of RSA.


- K

Re: Transmission of DSA signature

Hi Kaleb,

I looked up the RFC, and it turns out that the expected encoding is actually quite simple and I can implement it myself.
It is simply a sequence of two integers, while the wc_EncodeSignature function does something completely different, If
I am reading the source code correctly, this function is encoding the output of the hash function (SHA256 in my case).

Thanks for your time and patience, best regards

Nelson

Share