5

I'm trying to extract an ECDSA public key from my known_hosts file that ssh uses to verify a host. I have one below as an example.

This is the entry for "127.0.0.1 ecdsa-sha2-nistp256" in my known_hosts file:

AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBF3QCzKPRluwunLRHaFVEZNGCPD/rT13yFjKiCesA1qoU3rEp9syhnJgTbaJgK70OjoT71fDGkwwcnCZuJQPFfo=

I ran it through a Base64 decoder to get this:

���ecdsa-sha2-nistp256���nistp256���A]2F[rUF=wXʈ'ZSzħ2r`M::WL0rp

So I'm assuming those question marks are some kind of separator (no, those are lengths). I figured that nistp256 is the elliptical curve used, but what exactly is that last value?

From what I've been reading, the public key for ECDSA has a pair of values, x and y, which represent a point on the curve. Is there some way to extract x and y from there?

I'm trying to convert it into a Java public key object, but I need x and y in order to do so.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
loosebazooka
  • 2,363
  • 1
  • 21
  • 32

2 Answers2

7

Not all of characters are shown since they are binary. Write the Base64-decoded value to the file and open it in a hex editor.

The public key for a P256 curve should be a 65-byte array, starting from the byte with value 4 (which means a non-compressed point). The next 32 bytes would be the x value, and the next 32 the y value.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48
  • So ECDSA is fixed length? I was looking through some stuff about ssh-rsa (and ssh-dsa), are those not fixed length? It looks like some length is prefixing each key part. Is that true? – loosebazooka Feb 08 '13 at 23:50
  • ECDSA components are normally represented using a fixed length notation, but not always. Yes, some length is prefixed for each value, that is correct, see my answer. – Maarten Bodewes Feb 09 '13 at 01:35
5

Here is the result in hexadecimal:


Signature algorithm:

00 00 00 13
65 63 64 73 61 2d 73 68 61 32 2d 6e 69 73 74 70 32 35 36
(ecdsa-sha2-nistp256)

Name of domain parameters:

00 00 00 08
6e 69 73 74 70 32 35 36
(nistp256)

Public key value:

00 00 00 41
04
5d d0 0b 32 8f 46 5b b0 ba 72 d1 1d a1 55 11 93 46 08 f0 ff ad 3d 77 c8 58 ca 88 27 ac 03 5a a8
53 7a c4 a7 db 32 86 72 60 4d b6 89 80 ae f4 3a 3a 13 ef 57 c3 1a 4c 30 72 70 99 b8 94 0f 15 fa

So you first have the name of the digital signature algorithm to use, then the name of the curve and then the public component of the key, represented by an uncompressed EC point. Uncompressed points start with 04, then the X coordinate (same size as the key size) and then the Y coordinate.

As you can see, all field values are preceded by four bytes indicating the size of the field. All values and fields are using big-endian notation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Yeah I finally figured out that the "separators" were all lengths and the key part had had one single length prefixing it. – loosebazooka Feb 09 '13 at 16:36
  • @owlstead, any idea how this works with nistp521? Being 521 bit, that is 65.125 bytes, so do they use a padded 66 byte buffer and another padded 66 byte buffer, or do they use a combined 131 byte buffer and unpack the bits at 521 and 521 (with 6 bits left over)? – Lucas Oct 12 '13 at 22:02
  • Normally everybody uses padding on the integers, not on the combined values. Those functions are commonly called I2OS or similar (integer to octet string). – Maarten Bodewes Oct 12 '13 at 22:20