[pycrypto] Verify DSA bytestring signature

Winston Weinert winston at ml1.net
Tue Apr 8 04:45:23 PDT 2014


Thank you for your patience.

Unbeknownst to me what I wanted is indeed the sha1 digest of the zipfile’s sha1 digest. (So the first suggestion you wrote is what I needed.) It sounds funny, though is is how the library (the Sparkle Update Framework) I’m writing tools for does it.

Is it worthwhile for me to open a pull request enabling DSA.verify() to accept a base64 or the ASN.1 DER bytestring instead of the (r, s) tuple?

--
Winston


On Apr 7, 2014, at 6:50, Legrandin <helderijs at gmail.com> wrote:

> The openssl code is using SHA-1 twice: once to create the digest of the archive (dgst -sha1) and a second time when computing the DSA signature (dgst -dss1).
> 
> If your goal is to sign the hash, the Python code should actually read:
> 
> >> return pubkey.verify(SHA1.new(zipfile_digest).digest(), signature)
> 
> If your goal is to sign only the archive, the openssl code should be:
> 
> >> | openssl dgst -dss1 -sign "$DSA_PRIVKEY"  < "$RELEASE_ARCHIVE" \
> >> | openssl enc -base64
> 
> 2014-04-07 0:49 GMT+02:00 Winston Weinert <winston at ml1.net>:
> The signature is created using the openssl(1) command-line tool like this:
> 
> openssl dgst -sha1 -binary < "$RELEASE_ARCHIVE" \
> | openssl dgst -dss1 -sign "$DSA_PRIVKEY" \
> | openssl enc -base64
> 
> It verifies correctly using this command-line:
> 
> echo "$SIGNATURE” | openssl enc -base64 -d > /tmp/decoded_signature
> openssl dgst -sha1 -binary < "$RELEASE_ARCHIVE" > /tmp/release_archive_sha1
> openssl dgst -dss1 -verify "$DSA_PUBKEY" -signature /tmp/decoded_signature /tmp/release_archive_sha1
> 
> After I wrote my email, I dug around for awhile. After a lot of research I learned
> about ASN.1 DER’s usage in Dss-Sig-Value (http://www.ietf.org/rfc/rfc2459.txt). I
> wrote this code that appeared to decode my Base64 encoded signature correctly (I
> checked against http://lapo.it/asn1js/):
> 
> def decode_DSA_signature(signature):
>     raw_signature = base64.b64decode(signature)
>     der = DerSequence()
>     der.decode(raw_signature)
>     return (der[0], der[1])
> 
> Unfortunately .verify() returns False on correctly verified signature and hash
> pairs. I am using this new function like so:
> 
> 
> def validate(dsa_pubkey, signature, zipfile):
>     with open(dsa_pubkey, 'rb') as f:
>         pubkey = DSA.importKey(f.read())
>     with open(zipfile, 'rb') as f:
>         h = SHA1.new()
>         h.update(f.read())
>         zipfile_digest = h.digest()
>     signature = decode_DSA_signature(signature)
> 
>     return pubkey.verify(zipfile_digest, signature)
> 
> Maybe there is a problem with PyCrypto DSA and my environment?
> >>> sys.version
> '2.7.6 (default, Feb  7 2014, 12:51:34) \n[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)]'
> 
> For the time being I’m invoking openssl(1) for this task.
> 
> Thank you for the reply!
> Winston Weinert
> 
> 
> On Apr 6, 2014, at 4:50, Legrandin <helderijs at gmail.com> wrote:
> 
> > How was the signature created exactly?
> >
> > The .verify() method of a DSA object requires two integers, and there are several ways to encode them into a bytestring. It's very hard to guess the correct one for your case.
> >
> > FYI, there is a long standing pull request I created to add a saner DSA API:
> >
> > https://github.com/dlitz/pycrypto/pull/53
> >
> > The verification method accepts DER or big-endian encoded signatures.
> >
> >
> >
> > 2014-04-05 21:03 GMT+02:00 Winston Weinert <winston at ml1.net>:
> > Hello,
> >
> > I noticed in Git there is a “verify” method on Crypto.PublicKey.DSA. How do
> > I go about using this method? It wants a tuple, but unsure how to create
> > the appropriate tuple from my bytestring (which is decoded base64 text).
> > This is git revision 2d1aecd. The relevant code and error:
> >
> > Code:
> >
> > def validate(dsa_pubkey, signature, zipfile):
> >     with open(dsa_pubkey, 'rb') as f:
> >         pubkey = DSA.importKey(f.read())
> >     with open(zipfile, 'rb') as f:
> >         h = SHA1.new()
> >         h.update(f.read())
> >         zipfile_digest = h.digest()
> >     decoded_signature = base64.b64decode(signature)
> >
> >     return pubkey.verify(zipfile_digest, decoded_signature)
> >
> > Error:
> >
> > Traceback (most recent call last):
> >   File "sparkle_tool.py", line 67, in <module>
> >     validate_files(appcast, dsa_pubkey)
> >   File "sparkle_tool.py", line 55, in validate_files
> >     if validate(dsa_pubkey, signature, local_file):
> >   File "sparkle_tool.py", line 33, in validate
> >     return pubkey.verify(zipfile_digest, decoded_signature)
> >   File "/home/winston/jobber/venv/local/lib/python2.7/site-packages/Crypto/PublicKey/DSA.py", line 222, in verify
> >     return pubkey.pubkey.verify(self, M, signature)
> >   File "/home/winston/jobber/venv/local/lib/python2.7/site-packages/Crypto/PublicKey/pubkey.py", line 126, in verify
> >     return self._verify(M, signature)
> >   File "/home/winston/jobber/venv/local/lib/python2.7/site-packages/Crypto/PublicKey/DSA.py", line 240, in _verify
> >     (r, s) = sig
> > ValueError: too many values to unpack
> >
> > Thanks a bunch!
> > —
> > Winston Weinert
> > winston at ml1.net
> > _______________________________________________
> > pycrypto mailing list
> > pycrypto at lists.dlitz.net
> > http://lists.dlitz.net/cgi-bin/mailman/listinfo/pycrypto
> >
> > _______________________________________________
> > pycrypto mailing list
> > pycrypto at lists.dlitz.net
> > http://lists.dlitz.net/cgi-bin/mailman/listinfo/pycrypto
> 
> _______________________________________________
> pycrypto mailing list
> pycrypto at lists.dlitz.net
> http://lists.dlitz.net/cgi-bin/mailman/listinfo/pycrypto
> 
> _______________________________________________
> pycrypto mailing list
> pycrypto at lists.dlitz.net
> http://lists.dlitz.net/cgi-bin/mailman/listinfo/pycrypto

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dlitz.net/pipermail/pycrypto/attachments/20140408/68897330/attachment.html>


More information about the pycrypto mailing list