How to use SHA1 digest during signing with OpenSSL::PKCS7.sign when creating SMIME message

Viewed 965

The following code

body = "This is the message body"
pkcs7 = OpenSSL::PKCS7.sign @certificate, @pkey, body
pkcs7.detached = true
smime_signed = OpenSSL::PKCS7.write_smime pkcs7, body

will generate

MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----F1B5E0635C071F76431AEFB127A7DF88"

This is an S/MIME signed message

------F1B5E0635C071F76431AEFB127A7DF88
This is the message body
------F1B5E0635C071F76431AEFB127A7DF88
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIIHSgYJKoZIhvcNAQcCoIIHOzCCBzcCAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggRqMIIEZjCCA06gAwIBAgIQQNnrBxVw4uQUu6QaUH9huTANBgkq
[omitted]

Is it possible to set a custom digest, like OpenSSL::Digest::SHA1.new for the micalg? And if so, how?

I've tried the following:

pkcs7 = OpenSSL::PKCS7.new
pkcs7.type = :signed
signer = OpenSSL::PKCS7::Signer.new(@certificate, @pkey, OpenSSL::Digest::SHA1.new)
pkcs7.add_data body
pkcs7.add_certificate(@certificate)
pkcs7.add_signer signer
pkcs7.detached = true
smime_signed = OpenSSL::PKCS7.write_smime pkcs7, body

this will generate

MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="----0986A4FB87D37510B8051AB492BBF7A2"

This is an S/MIME signed message

------0986A4FB87D37510B8051AB492BBF7A2
This is the message body
------0986A4FB87D37510B8051AB492BBF7A2
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIIFcwYJKoZIhvcNAQcCoIIFZDCCBWACAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3
DQEHAaCCBGowggRmMIIDTqADAgECAhBA2esHFXDi5BS7pBpQf2G5MA0GCSqGSIb3
[omitted]

This seems to work and change the micalg, but the difference is pkcs7#data now returns #<OpenSSL::PKCS7:0x007fbe866d9420 @data=nil>

So, is it possible to use a different digest with OpenSSL::PKCS7.sign? And if not, what is the equivalent of

body = "This is the message body"
pkcs7 = OpenSSL::PKCS7.sign @certificate, @pkey, body
pkcs7.detached = true
smime_signed = OpenSSL::PKCS7.write_smime pkcs7, body

in openssl?

1 Answers

I do not know if it is possible to specify the digest algorithm using the Ruby bindings, but the equivalent OpenSSL command is:

openssl smime -sign -in body.txt -out out.txt -signer cert.pem -inkey key.pem -md sha1

You can verify the digest signature with:

openssl smime -verify -in out.txt -noverify
Related