1

The following command is used to sign a string via openssl:

smime -sign -signer cert.crt -inkey key.key -engine gost -binary -noattr

Given a .cer file that was said to contain key within self how to I execute the same command?

I'd assume 2 options:

  1. Rewrite the command to use internal key
  2. Convert .cer file to .crt and extract .key from it to be used w/o rewriting existing command

Update: The file insides are as follows: (using openssl x509 -in cert.cer -noout -text, replaced sensitive data with X_X_X):

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            X_X_X
        Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)
        Issuer: X_X_X
        Validity
            X_X_X
            X_X_X
        Subject: X_X_X
        Subject Public Key Info:
            Public Key Algorithm: GOST R 34.10-2012 with 256 bit modulus
            Unable to load Public Key
842D0000:error:03000072:digital envelope routines:X509_PUBKEY_get0:decode error:crypto\x509\x_pubkey.c:458:
842D0000:error:03000072:digital envelope routines:X509_PUBKEY_get0:decode error:crypto\x509\x_pubkey.c:458:
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement
            X509v3 Subject Alternative Name:
                othername: title::<unsupported>
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication, 1.2.643.2.1.6.8.5, 1.2.643.3.61.502710.1.6.3.2, 1.2.643.3.251.1.1, 1.2.643.3.251.3
            X509v3 Certificate Policies:
                Policy: Class of Signing Tool KC1
            1.2.643.100.114:
                ...
            Signing Tool of Subject:
                X_X_X
            Signing Tool of Issuer:
                signTool    : X_X_X
                cATool      : X_X_X
                signToolCert: X_X_X
                cAToolCert  : X_X_X
            X509v3 CRL Distribution Points:
                Full Name:
                  X_X_X
                Full Name:
                  X_X_X
            Authority Information Access:
                CA Issuers - X_X_X
                CA Issuers - X_X_X
            X509v3 Subject Key Identifier:
                X_X_X
            X509v3 Authority Key Identifier:
                keyid:X_X_X
                DirName:X_X_X
                serial:X_X_X
    Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)
    Signature Value:
        X_X_X
Nick Farsi
  • 366
  • 4
  • 19
  • Can you try the `-keyform P12` option for the command? Please let me know if that works so I can post an inforrmative answer. – Maarten Bodewes Sep 05 '22 at 10:38
  • Using this option the error is: ```Error loading PKCS12 file for signing key file unable to load signing key file``` – Nick Farsi Sep 05 '22 at 10:41
  • Do you have any more information on the file containing the certificate and key? What does it look like internally? If you're using Unix like OS, what does `file ` display? Certificates themselves only can contain a public key, but there are (file) formats such as those specified PKCS#12 that can contain both a certificate (chain) and a private key. Currently we don't have enough information to discern which format it used. – Maarten Bodewes Sep 05 '22 at 10:43
  • added requested data to the question body – Nick Farsi Sep 05 '22 at 10:51
  • 1
    If `openssl x509` (without `-inform`) reads the file it is PEM format. PEM format files are readable by humans; just look at it with any editor like vi nano emacs notepad etc, or display it with cat type more less or similar. You should see one or more sections that begin with `-----BEGIN SOMETHING-----` and end with `-----END SOMETHING-----`. What _exactly_ are the somethings? In particular is any of them `XXX PRIVATE KEY` for any value of XXX? – dave_thompson_085 Sep 05 '22 at 11:29
  • Using VS Code I see a 21 line text content with mostly broken encoding and some cyrillic/latin words. Nothing similar to begin / end / private – Nick Farsi Sep 05 '22 at 11:38
  • I have used the following command ```openssl x509 -in cert.cer -inform der -text``` to find only BEGIN CERTIFIATE & END CERTIFICATE statements – Nick Farsi Sep 05 '22 at 11:57
  • I see some data about Public Key: Subject Public Key Info: Public Key Algorithm: GOST R 34.10-2012 with 256 bit modulus Unable to load Public Key 78360000:error:03000072:digital envelope routines:X509_PUBKEY_get0:decode error:crypto\x509\x_pubkey.c:458: 78360000:error:03000072:digital envelope routines:X509_PUBKEY_get0:decode error:crypto\x509\x_pubkey.c:458: – Nick Farsi Sep 05 '22 at 12:26
  • First of all, I don't see any hint of a private key, which you would obviously need for signing. Second, adding a GOST engine doesn't auto-fix any issues with decoding GOST public keys in certificates. – Maarten Bodewes Sep 05 '22 at 12:37
  • 1
    Am I right to understand that having a private key inside a certificate makes the whole encryption thing pointless? – Nick Farsi Sep 05 '22 at 12:39
  • "Am I right to understand that having a private key inside a certificate makes the whole encryption thing pointless?" This is not how things work. A certificate is a public key and some metadata, and that is all. Don't be fooled by filenames extensions, they are MEANINGLESS. For a computer, the keyfile can be called `foobar.42` and the certificate `barbuz.666` and it will work the same way. Humans use extensions to simplify their life, that is all. The standard defines two encoding, either PEM or DER, and then various wrapper, to store either a certificate, a private key, or both. – Patrick Mevzek Sep 05 '22 at 14:17
  • Your question says `openssl x509` WITHOUT `-inform der` but your comment says WITH. THOSE ARE VERY DIFFERENT. Unlike a PEM file a DER file is NOT suitable for editing or display. A PEM file can contain multiple blocks and in particular can include both a certificate and a privatekey, but a DER file cannot, so you do NOT have a privatekey and cannot sign. – dave_thompson_085 Sep 05 '22 at 18:25
  • @dave_thompson_085 I don't think you're right with regard to a DER file never including a key. In fact, a PEM file is just the DER binary data in base-64 encoded text format. See also [this answer](https://stackoverflow.com/a/22743616/4850949). – not2savvy Sep 07 '22 at 08:53
  • 1
    @not2savvy: PEM is DER in base64 _with_ linebreaks and labels; see wikipedia or rfc7468. You can have a key _or_ a cert in a DER file but not both; in contrast a PEM file (as per initial edit) _can_ contain both because the labels delimit and identify each. Since we (now) know the file here was read by `openssl x509 -inform der` it contains a DER cert and cannot contain a DER key. I should however have stated non-PKCS12; PKCS12 can and usually does contain both, and is technically DER, but is not described as such because there is no PEM form. And `openssl x509` can't read PKCS12. – dave_thompson_085 Sep 07 '22 at 23:32

1 Answers1

1

I guess there are several things to be noted.

The file suffix

First of all, it should be noted that there is nothing like "a .crt or .cer file" as suggested in the question. These are just file suffixes from which you cannot derive the actual file format.

For example, a .cer file created in Windows will usually be in DER (binary) format, while openssl defaults to PEM (base-64 text) format. The very same is true for for .crt which is just more commonly used suffix in Windows. Other suffixes are .der and .pem which suggest that their suffix and format match.

openssl can handle both formats. You can let openssl know the input format using the -inform der or -inform pem option.

The private key

I assume you want to sign an email message, because you are using the smime option (although you speak of signing a string, but that may just be the same in you context).

In order to sign a message, you need a private key. If the S/MIME certificate file you have been given obviously includes the private key (sometimes referred to as a private certificate), it should not be necessary to extract the key first. Just do not use the -inkey option.

Quoted from the openssl smime docs:

If this option is not specified then the private key must be included in the certificate file specified with the -recip or -signer file.

To create a cleartext signed message using a certificate in PEM format, use

openssl smime -sign -in message.txt -text -out mail.msg -signer cert.crt

The certificate file cannot be in DER format if it includes the private key, because the DER format can hold only 1 object, so certificate and private key would need to be in separate DER files. See also this answer about the difference between PEM and DER. (Thanks to dave_thompson_085 for correcting me.)

not2savvy
  • 2,902
  • 3
  • 22
  • 37
  • 1
    I don't know what you mean by a 'private certificate'; no certificate, SMIME or other, contains a privatekey. A PKCS12 file (called PFX on Windows) does, but `openssl` supports PKCS12/PFX only in the specific `openssl pkcs12` command not relevant to this Q. `openssl smime -sign -inform der` is useless; on `smime`, `-inform` or `-outform` applies to the input/output _message_ (or detached sig) making it PKCS7/CMS instead of SMIME, not the cert OR key, and for `-sign` there is no input message. (In contrast `openssl x509 -inform/outform der` DOES affect the cert.) – dave_thompson_085 Sep 07 '22 at 23:37
  • @dave_thompson_085 Thanks for pointing that out. 'Private certificate' isn't correct terminology, but we often use it as a short form for a 'certificate plus its private key'. I edited my answer accordingly. – not2savvy Sep 08 '22 at 15:45
  • @dave_thompson_085 With regard to `-inform der`, again thanks for the comment. I wasn't aware that DER can hold only one object. My software offers DER when exporting certificate and key, so my assumptions was it would be possible. I've made some tests using openssl and they confirmed what you say. I'll edit my answer accordingly. – not2savvy Sep 08 '22 at 15:55