5

I found the following code online and apparently it works. But I don't understand the lines which extract the Bitcoin compatible private/public key from the created ECDSA keypair.

FILE_NAME=$1
PRIVATE_KEY=${FILE_NAME}_private.pem
PUBLIC_KEY=${FILE_NAME}_public.pem
BITCOIN_PRIVATE_KEY=bitcoin_${FILE_NAME}_private.key
BITCOIN_PUBLIC_KEY=bitcoin_${FILE_NAME}_public.key

echo "Generating private key"
openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out $PRIVATE_KEY

echo "Generating public key"
openssl ec -in $PRIVATE_KEY -pubout -out $PUBLIC_KEY

echo "Generating BitCoin private key"
openssl ec -in $PRIVATE_KEY -outform DER|tail -c +8|head -c 32|xxd -p -c 32 > $BITCOIN_PRIVATE_KEY

echo "Generating BitCoin public key"
openssl ec -in $PRIVATE_KEY -pubout -outform DER|tail -c 65|xxd -p -c 65 > $BITCOIN_PUBLIC_KEY

echo "Files created!"

If someone could explain, that would be nice

4 Answers 4

9

Bitcoin uses ECDSA so ECDSA keypairs are Bitcoin keypairs as well.

echo "Generating private key"
openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out $PRIVATE_KEY

This generates the private key in the pem format that openssl uses.

echo "Generating public key"
openssl ec -in $PRIVATE_KEY -pubout -out $PUBLIC_KEY

This generates the public key from the provided private key (which we just generated) and writes it to a file in the pem format.

echo "Generating BitCoin private key"
openssl ec -in $PRIVATE_KEY -outform DER|tail -c +8|head -c 32|xxd -p -c 32 > $BITCOIN_PRIVATE_KEY

This takes the private key in the pem format, converts it to the DER format, and extracts from that format the 32 bytes for the private key and writes those as a hex string to a file.

echo "Generating BitCoin public key"
openssl ec -in $PRIVATE_KEY -pubout -outform DER|tail -c 65|xxd -p -c 65 > $BITCOIN_PUBLIC_KEY

This takes the public key in the pem format, converts it to the DER format, and extracts from that format the 65 bytes for the public key and writes those as a hex string to a file.

3
  • 1
    Ok, so the "magic" I was missing is basically a format conversion.Thanks!
    – soupdiver
    Sep 17, 2017 at 15:59
  • @Adrew echo "Generating BitCoin public key" openssl ec -in $PRIVATE_KEY -pubout -outform DER|tail -c 65|xxd -p -c 65 > $BITCOIN_PUBLIC_KEY this takes private key not public key in pem version. Why I have to create $PUBLIC_KEY ?
    – monkeyUser
    Jan 24, 2019 at 14:53
  • You need the public key in pem form so that you can do public key operations with openssl. However, depending on what you are doing, it may not be necessary. I do not know what the original author's intent for this code was; my answer is only explaining what it does.
    – Andrew Chow
    Jan 24, 2019 at 17:19
2

Generation of both PrivKey and PubKey:

openssl ecparam -genkey -name secp256k1 -text -noout -outform DER | xxd -p -c 1000 | sed 's/41534e31204f49443a20736563703235366b310a30740201010420/PrivKey: /' | sed 's/a00706052b8104000aa144034200/\'$'\nPubKey: /'

Gives following result:

PrivKey: 1f7ca3635605bc57b579b5fdf73e3ac84aa91a9c8eddc57aa0e3452d1a429ff8
PubKey: 0403af2a877e578086b277c6aa0622ed1bd0754cac48acdfff6591d235fa517d739ded3fd6b7e6394a4023623d67a35c836f853213d9709033f310996230469917

Or just:

openssl ecparam -genkey -name secp256k1 -text -noout -outform DER | xxd -p -c 1000 | sed 's/41534e31204f49443a20736563703235366b310a30740201010420//' | sed 's/a00706052b8104000aa144034200/\'$'\n/'

Gives 2 following lines:

5be716d6bb3661a21cae21599bd94943508ba6566809705d2a1d6800741ac4e0
0424142e22f2fb297a804dda51b5a635ba871fba5d09b6133ac23da76433ccb97f727261262c40265c22040e96c275c5e682c698bc346d9e712222170d262647d1

To get Public Key from Private Key (replace *** with private key):

$ /usr/local/Cellar/openssl/1.0.2n/bin/openssl ec -inform DER -text -noout -in <(cat <(echo -n "302e0201010420") <(echo -n "***") <(echo -n "a00706052b8104000a") | xxd -r -p) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n' && echo

Full investigation is here: https://stackoverflow.com/a/49213805/440168

1
1

I would strongly recommend using /dev/random instead of /dev/urandom And, if you do it in VirtualBox you should share your host's /dev/random since the level of entropy in guest OS is low.

0
openssl ecparam -genkey -name secp256k1 -text -noout -outform DER | xxd -p -c 1000 | sed 's/41534e31204f49443a20736563703235366b310a30740201010420//' | sed 's/a00706052b8104000aa144034200/\'$'\n/'

for the above code... you're not creating bitcoin address but etheruem address

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.