Wanted to know command of openssl smime -sign to get digest value .

Something like below -

MIME-Version: 1.0
Content-Type: multipart/signed;protocol="application/pkcs7-

This is an S/MIME signed message

Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"



What is the command to generate it ?

verifying using -

openssl smime -verify -in sign -CAfile Sign_Key.crt -out xmlwithdigest
openssl dgst -binary -sha256 infile  | openssl base64

then comparing digest value ?


Your message is clearly an attempt at an S/MIME clear-signed (aka detached signature) message, see rfc5751 sec 3.4.3 et pred, although it's not actually correct; the first part, which is the data entity, does not have MIME headers.

Some software including OpenSSL can handle this deviation, but OpenSSL (still!) creates detached signatures with subtype x-pkcs7-signature from v2 (rfc2311) not the pkcs7-signature from newer versions as your message has.

A PKCS7/CMS detached signature, as used in this type of S/MIME message, has several optional components that can be used or not. From the truncated data you show it is impossible to determine which options that message uses, and anyway you don't indicate whether you care about those options one way or the other.

What is the command to generate it ?

With OpenSSL, openssl smime -sign -sha256 -signer $certfile [-inkey $keyfile] without -nodetach creates a message in this format, except as I noted above using the older subtype with x-. The -inkey option can be omitted if the privatekey is included in the same file as the cert. You can optionally:

  • include or not the signer's cert
  • explicitly include additional (chain) cert(s)
  • use signedAttributes or not as described in the man page on your system or online. You can input from and output to named files or use stdin and stdout which can in turn be redirected or piped by the shell (or OS).

    Except for very old OpenSSL versions (0.9.8 or lower) you can also use openssl cms which is actually a superset of openssl smime and despite its name defaults to doing S/MIME -- to get either openssl smime or openssl cms to do CMS you must specify -outform for sign or encrypt or -inform for verify or decrypt!

The smime verify command in your Q verifies the S/MIME signature (and by default the applicable cert chain as well, but it appears you are using a standalone cert and thus there is no real chain) and then discards it, outputting only the signed data, which in your case is XML.

The outer tag <cms> could mean this data is intended to represent Cryptographic Message Syntax, the successor to PKCS7 (rfc5652 et pred), but this combination of data does not correspond to any CMS message. The names do suggest that it contains a hash value for a particular file; if you have a (purported) copy of that file and want to verify the hash against the file, OpenSSL cannot do this automatically (nor even the checking done by common Unix {md5,sha1,etc}sum -c commands using a simpler ad-hoc text format). To check manually, your second command is a correct start; to extract the hash from the XML you could do something like

 $ grep -Po '<digest>\K[^<]*' 

or if you don't have a grep with PCRE, there are equivalents with sed awk perl almost certainly covered by other Qs here; and then compare the two hash values with shell test "$x" == "$y" or [ "$x" == "$y" ], or bash,ksh,zsh [[, or awk or perl, or other methods.

OTOH if your problem is actually creating that XML body, OpenSSL can only do the hash value; the rest will have to use standard text tools, or possibly XML tools.

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.