Search code examples
opensslhexed25519

Reading HEX formatted private key back into OpenSSL


I generate an ED25519 key-pair:

$ openssl genpkey -algorithm ed25519 | openssl pkey -text
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIEp53xeY8qoDU5mi2h7O//pJnI5CXWHWI9SVhgjKq1kt
-----END PRIVATE KEY-----
ED25519 Private-Key:
priv:
    4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:
    fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:
    59:2d
pub:
    c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
    e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
    e3:30

Then I store the priv key in HEX for later use.

$ hex=4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:59:2d

According to another answer, the following should get me the original data, but instead I get an error:

$ echo $hex | xxd -r -ps > ed25519.der
$ cat ed25519.der | openssl pkey -inform der -noout -text
Could not read key from <stdin>

How can I correctly regenerate the ED25519 public key from the HEX private key?


Solution

  • How can I correctly regenerate the ED25519 public key from the HEX private key?

    As explained in Topaco's comment, hex is the encoded raw private key, i.e. only the 32-bytes of the ED25519 key. See this answer for more details.

    However openssl expects an input in the OpenSSL DER or PEM formats.

    So there will be two steps:

    1. Recreate an OpenSSL private key from the 32-byte hex key.
    2. Create an OpenSSL public key from the OpenSSL private key.

    Recreate an OpenSSL private key from the 32-byte hex key.

    In order to do that, you just need to add the following extra header bytes before the 32-byte hex key:

    ##### Creating a private DER key from the private hex key:
    header=30:2e:02:01:00:30:05:06:03:2b:65:70:04:22:04:20
    hex=4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:59:2d
    echo "${header}${hex}" | xxd -r -ps > ed25519.der
    

    You can now check the contents of the created DER file as follows:

    ##### Check contents of DER file:
    cat ed25519.der | openssl pkey -inform der -noout -text
    

    Output:

    ED25519 Private-Key:
    priv:
        4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:
        fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:
        59:2d
    pub:
        c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
        e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
        e3:30
    

    Optionally, you can also create a private key in the PEM format as follows:

    ##### Creating a private PEM key from the private DER key:
    openssl pkey -in ed25519.der -outform pem -out ed25519.pem
    

    Contents of ed25519.pem:

    -----BEGIN PRIVATE KEY-----
    MC4CAQAwBQYDK2VwBCIEIEp53xeY8qoDU5mi2h7O//pJnI5CXWHWI9SVhgjKq1kt
    -----END PRIVATE KEY-----
    

    Create an OpenSSL public key from the OpenSSL private key.

    To create a public key in the DER format:

    ##### Creating a public DER key from the private DER key:
    openssl pkey -in ed25519.der -outform der -pubout -out ed25519.pub.der
    

    To create a public key in the PEM format:

    ##### Creating a public PEM key from the private DER key:
    openssl pkey -in ed25519.der -outform pem -pubout -out ed25519.pub.pem
    

    Contents of ed25519.pub.pem:

    -----BEGIN PUBLIC KEY-----
    MCowBQYDK2VwAyEAyK+Un/miEJUtVDR1vpQt55rvnE58bYCu/SXjpNWw4zA=
    -----END PUBLIC KEY-----
    

    Optional: Printing out the 32-byte hex keys of the generated DER or PEM files for checking

    ##### Check contents of keys, but this time without cat:
    echo "=== Private DER key ==="
    openssl pkey -inform der -in ed25519.der -noout -text
    echo "=== Private PEM key ==="
    openssl pkey -inform pem -in ed25519.pem -noout -text
    echo "=== Public DER key ==="
    openssl pkey -pubin -inform der -in ed25519.pub.der -noout -text
    echo "=== Public PEM key ==="
    openssl pkey -pubin -inform pem -in ed25519.pub.pem -noout -text
    

    Output:

    === Private DER key ===
    ED25519 Private-Key:
    priv:
        4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:
        fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:
        59:2d
    pub:
        c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
        e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
        e3:30
    === Private PEM key ===
    ED25519 Private-Key:
    priv:
        4a:79:df:17:98:f2:aa:03:53:99:a2:da:1e:ce:ff:
        fa:49:9c:8e:42:5d:61:d6:23:d4:95:86:08:ca:ab:
        59:2d
    pub:
        c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
        e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
        e3:30
    === Public DER key ===
    ED25519 Public-Key:
    pub:
        c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
        e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
        e3:30
    === Public PEM key ===
    ED25519 Public-Key:
    pub:
        c8:af:94:9f:f9:a2:10:95:2d:54:34:75:be:94:2d:
        e7:9a:ef:9c:4e:7c:6d:80:ae:fd:25:e3:a4:d5:b0:
        e3:30