3

I'm trying to decrypt and verify a message generated by a third-party Java framework. The ZIP archive of the latter could be found here, and the RFC-compliant certificates are uploaded to a Dropbox storage.

This command almost gets me the correct result:

openssl cms -verify -in message_from_alice_for_bob.msg -inform DER -CAfile ehealth_root_ca.cer | openssl cms -decrypt -inform DER -recip bob_etk_pair.pem  | openssl cms -inform DER -cmsout -print

I can see the correct message in eContent, but how can I extract this? The only result I need is: This is a secret message from Alice for Bob written at Thu Mar 13 12:39:12 CET 2014

Verification successful
CMS_ContentInfo:
  contentType: pkcs7-signedData (1.2.840.113549.1.7.2)
  d.signedData:
    version: 1
    digestAlgorithms:
        algorithm: sha256 (2.16.840.1.101.3.4.2.1)
        parameter: NULL
    encapContentInfo:
      eContentType: pkcs7-data (1.2.840.113549.1.7.1)
      eContent:
        0000 - 54 68 69 73 20 69 73 20-61 20 73 65 63 72 65   This is a secre
        000f - 74 20 6d 65 73 73 61 67-65 20 66 72 6f 6d 20   t message from
        001e - 41 6c 69 63 65 20 66 6f-72 20 42 6f 62 20 77   Alice for Bob w
        002d - 72 69 74 74 65 6e 20 61-74 20 54 68 75 20 4d   ritten at Thu M
        003c - 61 72 20 31 33 20 31 32-3a 33 39 3a 31 32 20   ar 13 12:39:12
        004b - 43 45 54 20 32 30 31 34-                       CET 2014
    certificates:
      <ABSENT>
    crls:
      <ABSENT>
    signerInfos:
        version: 1
        d.issuerAndSerialNumber:
          issuer: C=BE, O=Federal Government, OU=eHealth-platform Belgium, CN=eH CA
          serialNumber: 11687039761893623079
        digestAlgorithm:
          algorithm: sha256 (2.16.840.1.101.3.4.2.1)
          parameter: NULL
        signedAttrs:
            object: contentType (1.2.840.113549.1.9.3)
            set:
              OBJECT:pkcs7-data (1.2.840.113549.1.7.1)

            object: signingTime (1.2.840.113549.1.9.5)
            set:
              UTCTIME:Mar 13 11:39:12 2014 GMT

            object: messageDigest (1.2.840.113549.1.9.4)
            set:
              OCTET STRING:
                0000 - 76 64 f2 6c 21 f7 8e 53-ea 12 42 03 38   vd.l!..S..B.8
                000d - a8 17 ff cc 5e 41 07 ed-ad 14 3b ab 49   ....^A....;.I
                001a - d0 b2 87 74 db f4                        ...t..
        signatureAlgorithm:
          algorithm: rsassaPss (1.2.840.113549.1.1.10)
          parameter: SEQUENCE:
    0:d=0  hl=2 l=  52 cons: SEQUENCE
    2:d=1  hl=2 l=  15 cons:  cont [ 0 ]
    4:d=2  hl=2 l=  13 cons:   SEQUENCE
    6:d=3  hl=2 l=   9 prim:    OBJECT            :sha256
   17:d=3  hl=2 l=   0 prim:    NULL
   19:d=1  hl=2 l=  28 cons:  cont [ 1 ]
   21:d=2  hl=2 l=  26 cons:   SEQUENCE
   23:d=3  hl=2 l=   9 prim:    OBJECT            :mgf1
   34:d=3  hl=2 l=  13 cons:    SEQUENCE
   36:d=4  hl=2 l=   9 prim:     OBJECT            :sha256
   47:d=4  hl=2 l=   0 prim:     NULL
   49:d=1  hl=2 l=   3 cons:  cont [ 2 ]
   51:d=2  hl=2 l=   1 prim:   INTEGER           :20
        signature:
          0000 - a9 d1 19 05 47 5c 9c 57-db 94 5f f3 3a 25 55   ....G\.W.._.:%U
          000f - b7 60 87 cd 07 02 43 16-21 a7 11 d6 a5 b4 be   .`....C.!......
          001e - 0f 46 d3 a6 2c 8c e8 1d-9b be 34 b1 49 38 85   .F..,.....4.I8.
          002d - 8b 26 b3 b7 3e 11 dd 6e-45 b7 42 d1 3c fe 87   .&..>..nE.B.<..
          003c - 92 52 9a 08 24 9e b8 bf-36 23 09 d0 7e 93 c5   .R..$...6#..~..
          004b - d7 b7 65 11 32 57 83 bc-71 e4 6f cd 2e 56 23   ..e.2W..q.o..V#
          005a - 64 e6 2d 53 23 a8 2d 73-92 fd a8 d7 1f 3e 02   d.-S#.-s.....>.
          0069 - ef 4e bc 46 dc d2 39 53-1d 12 7c 93 02 25 25   .N.F..9S..|..%%
          0078 - 59 40 72 e7 7b 51 3b fd-27 4d ab 21 3f 14 5c   Y@r.{Q;.'M.!?.\
          0087 - 77 b8 18 0b 8d 6c 9d b9-ab 7e b6 45 b3 bc d8   w....l...~.E...
          0096 - 79 36 06 22 aa b7 12 13-0c 0e 57 e9 fa ea 4c   y6."......W...L
          00a5 - 3e a4 07 de 6a 10 13 69-e9 c8 70 f2 ad f2 26   >...j..i..p...&
          00b4 - f0 71 96 e3 52 aa 74 b1-39 17 54 f1 b5 d8 d6   .q..R.t.9.T....
          00c3 - 2e 64 c2 f7 c5 d4 d3 52-1d 3c 83 61 65 9a 90   .d.....R.<.ae..
          00d2 - 39 07 a3 40 58 d1 53 1c-3c cf 67 49 e9 7a d3   [email protected].<.gI.z.
          00e1 - 3e 6c ac 83 51 e1 08 f4-eb e1 c5 54 58 b8 43   >l..Q......TX.C
          00f0 - d2 c0 2d 26 8f 16 53 c5-04 f0 36 b1 1f 2e 54   ..-&..S...6...T
          00ff - ec                                             .
        unsignedAttrs:
          <EMPTY>

If I try this:

openssl cms -verify -in message_from_alice_for_bob.msg -inform DER -CAfile ehealth_root_ca.cer | openssl cms -decrypt -inform DER  -recip bob_etk_pair.pem  | openssl cms -verify -inform DER

I get this error:

Verification successful
Verification failure
4433208768:error:2E09D08A:CMS routines:CMS_verify:signer certificate not found:crypto/cms/cms_smime.c:304:

I'm not sure what certificate is expected here?

Some extra info from the documentation:

About the encryption method:

Since message security relies on integrity, authenticity and confidentiality simply signing and encrypting a message does not suffice. Signing and Encrypting does not guarantee message authenticity because is vulnerable to “surreptitious forwarding”. A triple wrapped message is a message that has been signed, then encrypted, then signed again. Further details about these principles and the reasons behind why triple wrapping is required can be found in the paper “Defective Sign & Encrypt in S/MIME,PKCS#7, MOSS, PEM, PGP, and XML“ – Donald T. Davis (MIT)

About decrypting (unsealing):

The authentication certificate of the sender is included in each message.

This seems correct:

openssl cms -verify -in message_from_alice_for_bob.msg -inform DER -CAfile ehealth_root_ca.cer -cmsout -print  | grep -B 4 11687039761893623079

Output:

    certificates:
      d.certificate:
        cert_info:
          version: 2
          serialNumber: 11687039761893623079
--
    signerInfos:
        version: 1
        d.issuerAndSerialNumber:
          issuer: C=BE, O=Federal Government, OU=eHealth-platform Belgium, CN=eH CA
          serialNumber: 11687039761893623079

There is also a .Net library that does the decryption.

7
  • The second command is wrong (I'll explain in the answer later), but I understand what's wrong with it, so this is fine. OTOH, the first command is weird. Could you please explain what command you use to encrypt and sign the message?
    – ximaera
    Commented May 16, 2019 at 13:39
  • 1
    I didn't do the encryption. It is done with a java library that uses Bounty Castle. It's free to download here: ehealth.fgov.be/ehealthplatform/nl/data/file/view/… Here is some documentation about it: ehealth.fgov.be/ehealthplatform/nl/data/file/view/…
    – roeland
    Commented May 16, 2019 at 17:14
  • The files I use as test are available in that library. I did some conversions first. I can make these files available if you need them?
    – roeland
    Commented May 16, 2019 at 17:32
  • Yes, if you did some conversions or changes, please upload them somewhere.
    – ximaera
    Commented May 16, 2019 at 17:43
  • 1
    Ok, you can get them here: dropbox.com/s/i0trp0iawyjpre2/crypto_question_210283.zip?dl=0
    – roeland
    Commented May 16, 2019 at 19:13

2 Answers 2

4

First, you should know that a part of the answer to your question is an openssl bug report I've just filed.

Both openssl cms -sign and openssl cms -verify only handle S/MIME content. They, by coincidence, can also process any text data (though there's no promise that this functionality will be kept in future releases), but they are not designed to sign or verify any encrypted binary data, including, but not limited to, encrypted DER-encoded messages, as it is in your case (though the cms(1) manpage sort of assumes it is still possible).

What is no less important, those two would not detect if the input is in any other format, silently failing instead with a (somewhat obscure) error message:

$ cat msg.txt
This is a secret message from Alice for Bob written at Thu Mar 13 12:39:12 CET 2014
$ 
$ openssl cms -encrypt -outform DER -aes-256-cbc -in msg.txt cert.pem \
| openssl cms -sign -md sha256 -signer cert.pem -inkey key.pem -nodetach -outform DER \
| openssl cms -verify -inform DER -CAfile ca.pem -out msg_ver.txt
Verification successful
$
$ openssl cms -cmsout -in msg_ver.txt -print
Error reading S/MIME message
4404864620:error:0D0D40D1:asn1 encoding routines:SMIME_read_ASN1:no content type:asn_mime.c:440:
$ 
$ openssl cms -cmsout -in msg_ver.txt -inform DER -print
Error reading S/MIME message
4527457900:error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data:a_d2i_fp.c:247:
$

NB: this is as of 1.0.2r as well as 1.1.1b openssl versions — the latest ones at the time of writing.

It would probably stay the same way in future releases, though you'd better check that again if you're reading this circa 2020.

I will try to update the answer once the behaviour changes, though I hold no responsibility for not doing so.

Second, the output you see is a correct decrypted message in its entirety.

However, for reasons unbeknowst to me, whoever has provided you with the encrypted file did not just go the ordinary encrypt[1] -> sign[2] route, but instead did sign[1] -> encrypt[2] -> sign[3] instead. The signing in the steps 1 and 3 was done with different certificates, with serial numbers a2:30:b4:be:2b:89:05:27 and a2:30:b4:be:2b:89:05:23, respectively.

You have correctly handled backwards steps 3 and 2. To verify the last signature from the step 1, you need to find a certificate with the serial number a2:30:b4:be:2b:89:05:27, and the certificate you've provided has a serial number a2:30:b4:be:2b:89:05:23, four issued certificates away from what you should have had.

Here's how you can figure out the serial number of a certificate:

$ openssl x509 -in ehealth_root_ca.cer -noout -text | grep -A1 'Serial Number:'
        Serial Number:
            a2:30:b4:be:2b:89:05:23
$

Maybe the certificate necessary is located somewhere in the sources or examples of the library you're referring to.

(Here's a short openssl cms cookbook in case you need it — though it doesn't seem like you do.)

3
  • Are there other/better solutions then mine? I try to avoid Java/.Net, but I need a solid solution.
    – roeland
    Commented May 17, 2019 at 2:09
  • I believe your bug report is incomplete; if the input also contains newline (0A) then data is lost from 00 to 0A but resumes thereafter. ('Random' data including ciphertext should contain both equally, but DER metadata is more likely to have 00 than 0A.) And more importantly -sign -binary DOES work correctly for me, on both 1.0.2r and 1.1.1b. Commented May 17, 2019 at 7:08
  • -sign -binary may work, but -verify -binary still leaves corrupt data.
    – ximaera
    Commented May 17, 2019 at 12:30
-1

try to add -inform pem in the end of the command

openssl cms -decrypt -in message.txt -recip Cert1.pem -inkey Cert-PK.pem -inform pem
1
  • 1
    Is there a reason why the OP should try this?
    – schroeder
    Commented Jan 6, 2020 at 11:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .