Author

Topic: openssl making private/public keys for ethereum (Read 384 times)

newbie
Activity: 1
Merit: 0
I hope someone can help me with this… I'm asking in the bitcoin forum b/c question relates to secp256k1 & openssl.

Maybe this answer is not right for you because it's not about openssl. But people without heavy tech background trying to understand how secp256k1 works in ECC could use this guide. It helped me figure out things more or less https://yad.finance/blog/wallet-off-the-wall/

In short, this is what the process looks like:

1) Generate a private key using some degree of randomization. Along the lines of bitaddress.org or similar services.

2) Generate a public key from your private key using ECC (specifically the secp256k1 curve, which is a good fit for Ethereum).

3) Generate a public address out of the public key, which might also consist of generating a compressed public address, then refining this address, etc

Let me know if it helped Embarrassed
full member
Activity: 198
Merit: 130
Some random software engineer
That works as expected thank you! I really appreciate you taking the time to send the updated code. If I ever get another spendable merit I'll send it your way. ;0)

That's OK, I learnt stuff too Smiley
I used to know that it was possible to create a bitcoin key with openssl ecparam/ec and extract it from DER, but I didn't know that it was possible to rebuild a DER file from a key. I learnt that too today, and I'm pretty happy about it.

Have a nice day!
member
Activity: 154
Merit: 12
Live life to the fullest and focus on the positive
To sum up, the steps are (I've compressed the whole procedure to a smaller command list):

Code:
$  openssl ecparam -name secp256k1 -genkey -noout -outform DER | \
     openssl ec -inform DER -no_public -outform DER -out template.der
read EC key
writing EC key

$ head -c 7 template.der > header.bin
$ echo A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad | xxd -r -p > key.bin
$ tail -c +40 template.der > footer.bin
$ cat header.bin key.bin footer.bin > private_key.der

$ cat private_key.der | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l=  46 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:A114DAD00000000000FACED00000000000BAD000000000DECAF00C02BAD02BAD
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1

$ openssl ec -inform DER -in private_key.der -no_public 2>/dev/null | \
    openssl ec -inform PEM -outform DER -out private_key_fixed.der 2>/dev/null

$ openssl ec -check -inform DER -in private_key_fixed.der -noout -text
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:9f:7d:cb:14:14:21:77:d7:b9:48:78:c4:59:b6:
    3a:16:f4:12:80:84:49:b7:8f:a1:7b:e6:4c:d3:7f:
    ed:57:a6:42:12:07:e6:ca:95:e0:c5:15:c3:5f:d5:
    8c:af:ac:a8:b0:e7:d6:07:a3:3a:2c:5c:b1:6a:de:
    28:af:83:15:f7
ASN1 OID: secp256k1
EC Key valid.

$ rm *bin template.der private_key.der

You should be good this time. Could you check ?
Thanks you!

That works as expected thank you! I really appreciate you taking the time to send the updated code. If I ever get another spendable merit I'll send it your way. ;0)
full member
Activity: 198
Merit: 130
Some random software engineer
To sum up, the steps are (I've compressed the whole procedure to a smaller command list):

Code:
$  openssl ecparam -name secp256k1 -genkey -noout -outform DER | \
     openssl ec -inform DER -no_public -outform DER -out template.der
read EC key
writing EC key

$ head -c 7 template.der > header.bin
$ echo A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad | xxd -r -p > key.bin
$ tail -c +40 template.der > footer.bin
$ cat header.bin key.bin footer.bin > private_key.der

$ cat private_key.der | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l=  46 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:A114DAD00000000000FACED00000000000BAD000000000DECAF00C02BAD02BAD
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1

$ openssl ec -check -inform DER -in private_key.der -noout -text
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:9f:7d:cb:14:14:21:77:d7:b9:48:78:c4:59:b6:
    3a:16:f4:12:80:84:49:b7:8f:a1:7b:e6:4c:d3:7f:
    ed:57:a6:42:12:07:e6:ca:95:e0:c5:15:c3:5f:d5:
    8c:af:ac:a8:b0:e7:d6:07:a3:3a:2c:5c:b1:6a:de:
    28:af:83:15:f7
ASN1 OID: secp256k1
EC Key valid.

$ rm *bin template.der private_key.der

You should be good this time. Could you check ?
Thanks you!
full member
Activity: 198
Merit: 130
Some random software engineer
Hmm. I need to take a deeper look, may be I missed a thing. Let me a few hours and I'll do some experiments. I'll let you know!

Ok, I guess it was incomplete.

Code:
$ openssl ec -check -inform DER -in private_key.der  -noout
read EC key
EC Key Invalid!
140074609043200:error:1010207B:elliptic curve routines:ec_key_simple_check_key:invalid private key:crypto/ec/ec_key.c:373:

That's because I imported the private key in the file, but the public key is still in there and openssl won't regenerate it (I thinked so, but well, it doesn't).

Let's make a valid file:

Code:
$ openssl ec -inform DER -in private_key.der -no_public 2>/dev/null | openssl ec -inform PEM -outform DER -out private_key_fixed.der 2>/dev/null
$ openssl ec -check -inform DER -in private_key_fixed.der -noout -text
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:9f:7d:cb:14:14:21:77:d7:b9:48:78:c4:59:b6:
    3a:16:f4:12:80:84:49:b7:8f:a1:7b:e6:4c:d3:7f:
    ed:57:a6:42:12:07:e6:ca:95:e0:c5:15:c3:5f:d5:
    8c:af:ac:a8:b0:e7:d6:07:a3:3a:2c:5c:b1:6a:de:
    28:af:83:15:f7
ASN1 OID: secp256k1
EC Key valid.

This said, my initial steps are just taking a long way. I could sum up the stuff, I guess.
full member
Activity: 198
Merit: 130
Some random software engineer
Well heck this doesn't work as expected. Run the keccak hash on the public key and the address doesn't match the wallet address for the private key according to myetherwallet.com. 

             cat Key | grep pub -A 5 | tail -n +2 |tr -d '\n[:space:]:' | sed 's/^04//' > pub

             cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41 > address

Seems the public key produced belongs to the original key file created when this command was ran:
openssl ecparam -name secp256k1 -genkey -noout > private.key

But I'm still going to call you a genius b/c that hack was pretty clever and taught me some things I didn't know. :0)

Hmm. I need to take a deeper look, may be I missed a thing. Let me a few hours and I'll do some experiments. I'll let you know!
member
Activity: 154
Merit: 12
Live life to the fullest and focus on the positive
A tricky way to do this is to make use of DER files, and to recreate one to import your key. This is a little hacky, but it works.

This is how I did it in a few minutes:

1/ First, create a private key (you won't use, you just need the file structure) in PEM format:

Code:
$ openssl ecparam -name secp256k1 -genkey -noout > private.key

We could directly create a DER file though, using a -outform DER, by the way.

1 (optional)/ What's cool about DER format is that you can dump in ASN.1 its structure. It is interesting and you should take a look at it:

Code:
$ cat private.key | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:BCDA55068C63324BB5CD05696264ED474467A3F1CC95CE83C00BC497F064F4B6
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING        

2/ From the private.key PEM file, convert it in DER and extract the header, the key, and the footer.

Code:
$ ll private.key
-rw-------. 1 mycroft mycroft 223 Mar 23 06:51 private.key
$ openssl ec -in private.key -outform DER 2>/dev/null|head -c 7 > header.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +8|head -c 32 > key.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +40 > footer.bin
$ ll *bin
-rw-rw-r--. 1 mycroft mycroft 79 Mar 23 06:53 footer.bin
-rw-rw-r--. 1 mycroft mycroft  7 Mar 23 06:53 header.bin
-rw-rw-r--. 1 mycroft mycroft 32 Mar 23 06:53 key.bin

3/ Replace the key I just created by yours

Code:
$ echo A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad | xxd -r -p > key.bin

4/ Rebuild & check the complete DER file

Code:
$ cat header.bin key.bin footer.bin > private_key.der
$ cat private_key.der | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:A114DAD00000000000FACED00000000000BAD000000000DECAF00C02BAD02BAD
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING        

See ? Same structure, different key! Voodoo magic!

5/ recreate your "Key" file:

Code:
$ openssl ec -in private_key.der -inform DER -text -noout
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:d5:53:99:c9:4d:1f:1f:7f:f1:5b:c5:13:d1:96:
    34:2b:c8:22:dc:23:9d:f0:55:d6:72:3c:f0:b6:2c:
    c8:20:e8:dd:13:40:4b:3a:0d:e5:64:ce:6a:20:e6:
    23:ee:2a:17:18:23:d0:6f:0b:13:30:4a:d7:f5:2a:
    c2:28:2e:40:33
ASN1 OID: secp256k1

And we're done.



You're a genius starmyc! Thank you for taking the time to explain this it works like a charm... Sent you the only sendable merit I had. ;0)

Well heck this doesn't work as expected. Run the keccak hash on the public key and the address doesn't match the wallet address for the private key according to myetherwallet.com. 

             cat Key | grep pub -A 5 | tail -n +2 |tr -d '\n[:space:]:' | sed 's/^04//' > pub

             cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41 > address

Seems the public key produced belongs to the original key file created when this command was ran:
openssl ecparam -name secp256k1 -genkey -noout > private.key

But I'm still going to call you a genius b/c that hack was pretty clever and taught me some things I didn't know. :0)
member
Activity: 154
Merit: 12
Live life to the fullest and focus on the positive
A tricky way to do this is to make use of DER files, and to recreate one to import your key. This is a little hacky, but it works.

This is how I did it in a few minutes:

1/ First, create a private key (you won't use, you just need the file structure) in PEM format:

Code:
$ openssl ecparam -name secp256k1 -genkey -noout > private.key

We could directly create a DER file though, using a -outform DER, by the way.

1 (optional)/ What's cool about DER format is that you can dump in ASN.1 its structure. It is interesting and you should take a look at it:

Code:
$ cat private.key | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:BCDA55068C63324BB5CD05696264ED474467A3F1CC95CE83C00BC497F064F4B6
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING        

2/ From the private.key PEM file, convert it in DER and extract the header, the key, and the footer.

Code:
$ ll private.key
-rw-------. 1 mycroft mycroft 223 Mar 23 06:51 private.key
$ openssl ec -in private.key -outform DER 2>/dev/null|head -c 7 > header.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +8|head -c 32 > key.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +40 > footer.bin
$ ll *bin
-rw-rw-r--. 1 mycroft mycroft 79 Mar 23 06:53 footer.bin
-rw-rw-r--. 1 mycroft mycroft  7 Mar 23 06:53 header.bin
-rw-rw-r--. 1 mycroft mycroft 32 Mar 23 06:53 key.bin

3/ Replace the key I just created by yours

Code:
$ echo A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad | xxd -r -p > key.bin

4/ Rebuild & check the complete DER file

Code:
$ cat header.bin key.bin footer.bin > private_key.der
$ cat private_key.der | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:A114DAD00000000000FACED00000000000BAD000000000DECAF00C02BAD02BAD
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING        

See ? Same structure, different key! Voodoo magic!

5/ recreate your "Key" file:

Code:
$ openssl ec -in private_key.der -inform DER -text -noout
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:d5:53:99:c9:4d:1f:1f:7f:f1:5b:c5:13:d1:96:
    34:2b:c8:22:dc:23:9d:f0:55:d6:72:3c:f0:b6:2c:
    c8:20:e8:dd:13:40:4b:3a:0d:e5:64:ce:6a:20:e6:
    23:ee:2a:17:18:23:d0:6f:0b:13:30:4a:d7:f5:2a:
    c2:28:2e:40:33
ASN1 OID: secp256k1

And we're done.



You're a genius starmyc! Thank you for taking the time to explain this it works like a charm... Sent you the only sendable merit I had. ;0)
full member
Activity: 198
Merit: 130
Some random software engineer
A tricky way to do this is to make use of DER files, and to recreate one to import your key. This is a little hacky, but it works.

This is how I did it in a few minutes:

1/ First, create a private key (you won't use, you just need the file structure) in PEM format:

Code:
$ openssl ecparam -name secp256k1 -genkey -noout > private.key

We could directly create a DER file though, using a -outform DER, by the way.

1 (optional)/ What's cool about DER format is that you can dump in ASN.1 its structure. It is interesting and you should take a look at it:

Code:
$ cat private.key | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE         
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:BCDA55068C63324BB5CD05696264ED474467A3F1CC95CE83C00BC497F064F4B6
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]       
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]       
   50:d=2  hl=2 l=  66 prim: BIT STRING       

2/ From the private.key PEM file, convert it in DER and extract the header, the key, and the footer.

Code:
$ ll private.key
-rw-------. 1 mycroft mycroft 223 Mar 23 06:51 private.key
$ openssl ec -in private.key -outform DER 2>/dev/null|head -c 7 > header.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +8|head -c 32 > key.bin
$ openssl ec -in private.key -outform DER 2>/dev/null|tail -c +40 > footer.bin
$ ll *bin
-rw-rw-r--. 1 mycroft mycroft 79 Mar 23 06:53 footer.bin
-rw-rw-r--. 1 mycroft mycroft  7 Mar 23 06:53 header.bin
-rw-rw-r--. 1 mycroft mycroft 32 Mar 23 06:53 key.bin

3/ Replace the key I just created by yours

Code:
$ echo A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad | xxd -r -p > key.bin

4/ Rebuild & check the complete DER file

Code:
$ cat header.bin key.bin footer.bin > private_key.der
$ cat private_key.der | openssl asn1parse -in - -inform DER
    0:d=0  hl=2 l= 116 cons: SEQUENCE         
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:A114DAD00000000000FACED00000000000BAD000000000DECAF00C02BAD02BAD
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]       
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]       
   50:d=2  hl=2 l=  66 prim: BIT STRING       

See ? Same structure, different key! Voodoo magic!

5/ recreate your "Key" file:

Code:
$ openssl ec -in private_key.der -inform DER -text -noout
read EC key
Private-Key: (256 bit)
priv:
    a1:14:da:d0:00:00:00:00:00:fa:ce:d0:00:00:00:
    00:00:ba:d0:00:00:00:00:de:ca:f0:0c:02:ba:d0:
    2b:ad
pub:
    04:d5:53:99:c9:4d:1f:1f:7f:f1:5b:c5:13:d1:96:
    34:2b:c8:22:dc:23:9d:f0:55:d6:72:3c:f0:b6:2c:
    c8:20:e8:dd:13:40:4b:3a:0d:e5:64:ce:6a:20:e6:
    23:ee:2a:17:18:23:d0:6f:0b:13:30:4a:d7:f5:2a:
    c2:28:2e:40:33
ASN1 OID: secp256k1

And we're done.

member
Activity: 154
Merit: 12
Live life to the fullest and focus on the positive
I hope someone can help me with this… I'm asking in the bitcoin forum b/c question relates to secp256k1 & openssl.

I understand how to make an ethereum public/private key & public address using linux commands.
From the command prompt three simple steps:

1)                openssl ecparam -name secp256k1 -genkey -noout | openssl ec -text -noout > Key
2)                cat Key | grep pub -A 5 | tail -n +2 |tr -d '\n[:space:]:' | sed 's/^04//' > pub
3)                cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41 >  address

Wala! All done! I’ve got a unique public/private key to use for my ethereum wallet.

But what I can’t figure out is how to input a set of numbers/letters into openssl and get the public/private keys like at the end of step 1.
Let’s say I like this ethereum private key but I need the public address to use it:

A114dad00000000000faced00000000000bad000000000decaf00c02bad02bad

I know I can go to an online wallet and enter the private key and get the public address which is:
0xB1607e934B61Fc1128AF1E8aa668e33d883aB3b9 (please nobody use this address keys are now public)
but I want to do this from linux prompt and get the answer.

My question: How do I enter that private key into openssl to get the private/public key pair returned something like this result?

Private-Key: (256 bit)
priv:
     0b:f3:29:aa:bf:d0:bb:0b:0f:e1:4b:80:54:f2:1a:
     2e:38:7d:cd:b5:9b:07:5f:3c:38:99:40:bd:5e:e4:
     a4:0f
pub:
     04:2f:06:55:11:4a:b1:90:11:00:a4:48:cb:6a:91:
     76:f3:01:50:2d:9f:8b:03:ab:cb:8b:67:e7:e7:d0:
     3f:85:de:e9:2a:76:59:12:94:4a:4a:ff:94:cd:d7:
     97:a2:6b:9c:ae:da:4e:ec:b0:1d:30:c0:55:14:90:
     b6:51:dd:75:09
 ASN1 OID: secp256k1   (please don’t use this key pair it’s now public)

Thanks in advance for any help… Openssl has really got me all messed up trying to figure this out.
Jump to: