Search code examples
goopensslcurve-25519

Parse curve25519 keys generated using openssl in Go


Using OpenSSL version 1.1 and or later, I'm able to generate a curve25519 key:

openssl genpkey -algorithm x25519

This produces a private key of the form:

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIDgk3GuFMIaUJd3m95jn/Z8oU+cK9FzPoidIDn/bqRlk
-----END PRIVATE KEY-----

I want to parse this key file in Go and potentially use it using golang.org/x/crypto/nacl/box. Looking at crypto/x509 documentation, I can't find a parsing function that parses curve25519. Anyone have an idea?

I tried:

pKey := `-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAfLLsWKkI/7EmTOkSf4fyHuRHDnKk6qNncWDzV8jlIUU=
-----END PUBLIC KEY-----`

block, _ := pem.Decode([]byte(pKey))
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
    fmt.Println(err)
}

I get the error unknown public key algorithm.


Solution

  • Since there is currently no way to parse X25519 keys in the standard library, you may have to do this “by hand”.

    You could do it “properly” by using the encoding/asn1 library to decode the keys, but in this case there is a simpler way.

    It turns out that for both the private and public keys the actual key is just the last 32 bytes of the base64 decoded block of the key.

    So you can just do:

    block, _ := pem.Decode([]byte(pemString))
    key := block.Bytes[len(block.Bytes)-32:]
    

    This will work for both public and private keys, and will give you a 32 byte []byte containing the appropriate key.