2

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.

bli00
  • 2,215
  • 2
  • 19
  • 46

2 Answers2

2

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.

matt
  • 78,533
  • 8
  • 163
  • 197
0

Your inline key value is malform due to the tab/spaces before -----END PUBLIC KEY-----

As a result block is nil and cause the follow-up function to segfault.

Here's a quick fix for the decoding piece:

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

block, _ := pem.Decode([]byte(pKey))

if block == nil || block.Type != "PRIVATE KEY" {
    log.Fatal("failed to decode PEM block containing private key")

}

key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
    log.Println("Parse PKI Error:", err)
    return
}

Playground: https://play.golang.org/p/O2wk8rmKGWH

Note: ParsePKIXPublicKey function does not recognize this key algorithm.

2009/11/10 23:00:00 Parse PKI Error: x509: unknown public key algorithm

colm.anseo
  • 19,337
  • 4
  • 43
  • 52
  • My apologies, StackOverFlow's editor failed to format my tabs correctly. I've fixed the question. The question still remains. There's no parsing function that recognizes curve25519. – bli00 Oct 01 '19 at 20:54
  • 1
    I think you need to clarify `Public` vs `Private` - the function in question is meant for a Public key - and your question has a private key definition. – colm.anseo Oct 01 '19 at 21:56
  • The key in my example is a public key and the function I used to parse it is for public keys. The question is irrespective of whether if it's a public or private key. There's no function to parse either. – bli00 Oct 01 '19 at 22:18
  • It is relevant. A private key contains both the private and public part. A public key just the public part. OpenSSL has this distinction and so too does the `x509` package. – colm.anseo Oct 01 '19 at 22:21
  • I understand that. But there's no function under the `x509` package that will parse the private or the public key file. `ParsePKIXPublicKey` is not the correct function. – bli00 Oct 01 '19 at 22:34