9

I am using openssl commands to create a CSR with elliptic curve secp384r1 and hash signed with algorithm sha384:

openssl ecparam -out ec_client_key.pem -name secp384r1 -genkey

openssl req -new -key ec_client_key.pem -out ec_clientReq.pem

Then I display the CSR in readable format with this command:

openssl req -in ec_clientReq.pem -noout -text

In the signature part of the CSR I get this:

Signature Algorithm: ecdsa-with-SHA1
    30:64:02:30:06:a1:f2:5e:1b:34:18:b9:f3:7c:e9:52:c8:78:
    99:90:63:d2:1e:d2:f5:7a:25:f3:d6:4d:6d:90:d0:bf:25:45:
    15:ad:aa:17:34:ad:1a:b9:1e:67:2b:cf:d7:a6:9b:e5:02:30:
    31:fe:76:37:4b:11:3a:e7:2d:63:52:bb:18:2f:8e:43:a7:bb:
    65:74:38:a4:92:38:9d:eb:ec:22:8f:77:f3:e4:5f:47:2d:f8:
    2a:9b:e1:2c:ba:a7:b0:e6:c2:54:8d:0e

What should I do in order to get a signature algorithm "ecdsa-with-SHA384" instead of "ecdsa-with-SHA1"? Am I missing something in this process? I tried to use -sha384 in the second command

openssl req -new -key ec_client_key.pem -out ec_clientReq.pem -sha384

but I got the same result regarding the Signature Algorithm

Signature Algorithm: ecdsa-with-SHA1
    30:65:02:30:4e:b4:b6:5f:3a:fc:b7:28:e5:4b:f0:3d:9a:ea:
    4a:ba:ce:a4:f1:a6:e8:cd:15:19:23:a6:81:3f:24:01:d7:81:
    3c:9d:9a:4c:cd:4b:4a:12:6d:69:48:ec:7e:73:7d:73:02:31:
    00:d7:a5:63:9b:21:b2:95:ce:7f:13:3f:c5:1a:ac:99:01:ff:
    ba:9c:59:93:d5:ee:97:03:b5:9e:c1:7d:03:f8:72:90:65:b5:
    08:7c:79:ae:ea:4f:6e:b0:2b:55:1a:11:a5

Another question regards the format of the signature. In the examples above one is 102 bytes long and the second one is 103 bytes long. It seems that the first bytes are an header including type, length and may be some other stuff like padding. But I cannot find an exact definition. Can someboby put some light on this? Thanks

gtrig
  • 12,550
  • 5
  • 28
  • 36
Gaston
  • 589
  • 1
  • 10
  • 34
  • 1
    This question appears to belong on another site in the Stack Exchange network because its not about programming. Perhaps [Super User](https://www.superuser.com/). – jww May 11 '14 at 10:52

3 Answers3

5

I tried again with last openssl version 1.0.1e this time (instead of 0.9.8n).

openssl ecparam -out ec_client_key.pem -name secp384r1 -gen

openssl req -config openssl.cnf -new -key ec_client_key.pem -out ec_clientReq.pem -sha384

openssl req -in ec_clientReq.pem -noout -text

Now I get the expected result:

Signature Algorithm: ecdsa-with-SHA384

It looks that version 0.9.8n does not support sha384.

This extract from the CHANGES file seems to confirm this:

Changes between 1.0.0h and 1.0.1 [14 Mar 2012] : ... *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. As required by RFC5289 these ciphersuites cannot be used if for versions of TLS earlier than 1.2. [Steve Henson]

Thanks gtrig for your help.

Gaston
  • 589
  • 1
  • 10
  • 34
2

When I use the same command you did with the -SHA384 option, I get this in the resulting CSR: "Signature Algorithm: ecdsa-with-SHA384".

Type this command to see the list of supported digests:

openssl list-message-digest-algorithms

Hopefully, you'll see SHA384 in that list.

About your 2nd question, the format is ASN.1. "30" indicates that a sequence follows (In this case, it's a sequence of 2 integers). "65" is the number of octets in the sequence. "02" represents an integer and 30 is the number of octets in that integer. If you skip ahead 0x30 (48 in decimal) octets, you'll come to the 2nd integer which is marked with "02" and "31". So the length of the first integer is 30 and the 2nd is 31. Add in the 2 octets for each integer and you get 65, which is the length of the sequence. This page can tell you more about ASN.1.

As far as this value being a sequence of 2 integers, that makes sense. The ECDSA signature is made up of 2 integers. See RFC6605 section 4 for more information. There is also the wiki page that explains how to calculate the 2 integers.

Community
  • 1
  • 1
gtrig
  • 12,550
  • 5
  • 28
  • 36
  • 1
    Thank you for your explanation about the signature format. It really helps a lot. Unfortunately I am running openssl version 0.9.8n and command list-message-digest-algorithms is not available there. I found out that flags CONFIG_CRYPTO_SHA256 and CONFIG_CRYPTO_SHA512 were not set in my kernel so I built it again with these flags on. But no result. I also added sha384 in list of supported digests in openssl.cnf but it didn't help too. – Gaston May 30 '13 at 13:20
  • Do you see SHA386 listed if you type "openssl dgst -foo"? The -foo part is obviously not a valid argument, but is used to display the usage, which will also list the digests. Also, have you tried this scenario with SHA256 or SHA512 instead to see if they work? – gtrig May 30 '13 at 14:10
  • When typing openssl dgst -foo the following is displayed: "-sha384 to use the sha384 message digest algorithm". Yes I tried SHA256 and SHA512 also and I always have ecdsa-with-SHA1 displayed in signature algorithm. – Gaston May 30 '13 at 14:43
  • Interesting. What if you try an invalid option like -sha777? Will it let you do that or does it give you an error as it should? What about a new version of OpenSSL? You can download the latest [here](http://www.openssl.org/source/). – gtrig May 30 '13 at 16:47
  • Still about signature format (2nd question) there is one point not clear; each one of the two integers of the DSA signatures can be either 48 (0x30) bytes long in or 49 (0x31) bytes long. In the first case the related sequence in the signature will start with 02:30: followed by 48 bytes 4e:b4:b6:..... In the second case the related sequence in the signature will start with start with 02:31: followed by a padding byte 00: and then 48 bytes d7:a5:63:... The question is what is the reason sometime there is a 0x00 byte padding and sometimes not? – Gaston Jun 05 '13 at 07:56
  • I believe the extra 0x00 byte is there because the high bit of the next number is a 1. 0xd7 is represented as 1101 0111 in binary. In some binary schemes, a high bit of 1 implies the number is negative. To avoid the confusion about a negative number, the extra 0x00 is added. The other 3 integers start with 4e, 06, and 31...which translate to binary as 0100 1110, 0000 0110, and 0011 0001. Notice with all 3 of them, the high bit is 0. – gtrig Jul 26 '13 at 02:06
  • The syntax that works for me is `openssl list -digest-algorithms`, using openssl version 1.1.0k – mc0e Sep 16 '19 at 03:05
1

To make the answer more complete, the generation of non-self-signed certificates with ecdsa-sha384 signature can be mentioned, because it is a bit different. The trick is to use "-md sha384" parameter with "openssl ca" command.

An example including client certificate

Generate key for certificate authority:

openssl ecparam -out ca.key -name secp384r1 -genkey

Create self signed certificate for ca:

openssl req -x509 -new -key ca.key -out ca-ca.pem -outform pem -sha384

Generate key for a client:

openssl ecparam -out host1.key -name secp384r1 -genkey

Create certificate request for client key:

openssl req -new -nodes -key host1.key -outform pem -out host1.req -sha384

Create certificate for client in response to request:

openssl ca -keyfile ca.key -cert ca-ca.pem -in host1.req
  -out ca-host1-cert.pem -md sha384 -outdir .