2
$\begingroup$

I would like to know how openssl verifies a digital signature? I know that it uses this command to verify a signature:

openssl dgst -sha256 -verify pkypem -signature signbin msgbin > result

What I want to know is, what openssl does exactly with the public key, the signature and the message before verification.

I'm also interested in the signature creation process.

$\endgroup$
5
+50
$\begingroup$

It depends on the type of key, and (thus) signature.

If it is an RSA key, by default OpenSSL uses the original PKCS1 'block type 1' signature scheme, now retronymed RSASSA-PKCS1-v1_5 and currently defined in PKCS1v2.2. OpenSSL commandline also supports the RSASSA-PSS scheme (commonly just PSS) defined in the preceding section of PKCS1v2.2, with the dgst -sigopt option (online copy of man page) whose relevant values are actually documented in the pkeyutl man page.

If it is a DSA key, OpenSSL implements the algorithm as specified by the standard, FIPS186 currently at revision -4 and available at https://csrc.nist.gov/publications/fips (edited: usually, but download currently hangs presumably due to the government shutdown even though the webpage does display which initially fooled me); a shorter, less bureaucratic and more reliably available description is in Wikipedia. One minor point not stated in FIPS186, or Wikipedia, is that the signature value, which is mathematically a pair of integers, is concretely represented using ASN.1 (as a SEQUENCE of two INTEGERs). (In contrast PKCS1 for RSA defines the representation of the signature, which is mathematically an integer in $[2,n-1]$, using the I2OSP and OS2IP primitives, as bigendian (unsigned) binary with size equal to that required to represent the modulus.)

If it is an EC key, OpenSSL implements ECDSA as specified by X9.62, which costs money, but is also available in document SEC1 at http://www.secg.org (which ironically can't easily be accessed by https because it has a mismatched certificate!), and again in Wikipedia. Again the signature is mathematically a pair of integers, represented in ASN.1.

All of the above sources cover signing, aka signature generation or creation, as well as verifying for a given algorithm.

If it is a GOST key, OpenSSL may or may not work depending on version and build or packaging; this support has fluctuated. And if it works I'm not familiar with what it does, except that it is somehow like ECDSA.

Note that the 'raw' format used by openssl dgst -sign/verify, and openssl pkeyutl -sign/verify which skips the (data) hashing step (and for RSASSA-PKCS1v1_5, optionally the ASN.1 encode/decode step), is not used by most other software. Most actual signatures (for things like emails and code files and XML or JSON data, and certificates and CRLs and OCSPs and timestamps, as well as the signatures used in protocols like SSL/TLS and SSH) are represented in a form that adds metadata about the signature algorithm and a way to find the publickey for verification, and often to validate that key, and sometimes contain or are attached to the data signed as well.

$\endgroup$
  • $\begingroup$ Do you know for RSA with PKCS#1 v1.5 if it uses the computed hash to regenerate the padding and compare the results or that it first verifies the padding, extracts the hash and compares that to the computed hash? Of course the modular exponentiation and hashing needs to be performed in a particular order, but in principle the padding could be ran both ways (for this particular deterministic RSA PKCS#1 v1.5 padded scheme anyway. $\endgroup$ – Maarten Bodewes Jan 20 at 16:46
  • 2
    $\begingroup$ @MaartenBodewes: through 1.1.0 it unpads the 01FF.., then handles two special cases (SSL3/TLS1.0-1.1 signatures with no ASN.1 and presumably very old MD2 signatures with nonstandard ASN.1), then decodes the DigestInfo (bizarrely naming the type X509_SIG) which implicitly allows BER and/or AlgId.parameters omitted rather than NULL (see 8017 9.2 note 2 and B.1 'Exception' which was not explicit in earlier versions). In 1.1.1 the two special cases remain, but the normal case is now encode-then-compare. $\endgroup$ – dave_thompson_085 Jan 22 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.