I want to understand how bitcoin works and I do not trust tools or bitcoin platforms.

I have read this on Internet. Can you confirm me this lines are generating a bitcoin public/private key safely ?

openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out tmp_private.txt
openssl ec -in tmp_private.txt -outform DER \
    | tail -c +8 | head -c 32 | xxd -p -c 32 > private.txt
openssl ec -in tmp_private.txt -pubout -outform DER \
    | tail -c 65 | xxd -p -c 65 > public.txt
rm tmp_private.txt

I know it is not a good thing to store private key in a basic clear text file, I just want to know if the way generating the key is good.

Is there an openssl command which can generate a bitcoin address from public.txt file?

  • Linux has shred which can be substituted for rm
    – Peleion
    May 6, 2020 at 19:05
  • 1
    Shred is notoriously unreliable for this stuff - modern filesystems, especially those with copy on write, or even SSDs and some HDDs will often use different blocks to store the shredded data - in many cases, the original keys will still be recoverable if you use shred. Oct 2, 2020 at 13:41

3 Answers 3


Yes, it's randomness is trustworthy, so it's safe.

The only problem I see is that "rm" does not remove all of its traces from the hard drive. The private key may be recovered. The pedantic way to erase such secrets is to use the Gutmann method which overwrites files 35 times.

To derive the address you need to use something like https://bitcoin.stackexchange.com/a/67093

  • The rm is not a problem for me i want to know if the previous lines are OK. The keys seems to be very small in fact...
    – Bob5421
    May 3, 2020 at 17:12
  • Yes it's correct and safe. The rand /dev/urandom argument specifies the randomness source which is also used by a dozen of crypto(currency) software including Bitcoin Core.
    – MCCCS
    May 3, 2020 at 17:37

The format written and read by most openssl commandline utilities, although it is textual in nature, is specifically PEM and usually named accordingly, not 'text' or 'txt' which can be (and frequently is) zillions of other formats that aren't PEM and wouldn't be usable here.

Some other things you can do with openssl that might help:

# instead of head/tail/etc you can use asn1parse -strparse to extract the private and public values
# but as raw/binary not hex:
$ openssl asn1parse <privpem -strparse 5 -out privraw >&/dev/null; od -Ax -tx1 privraw
000000 23 34 02 73 64 bb 35 79 f0 f5 25 76 f5 f9 5f df
000010 ff aa 94 d3 24 21 da c9 e3 2d 33 95 8b 8d 4f 1d
$ openssl asn1parse <privpem -strparse 50 -out pubraw >&/dev/null; od -Ax -tx1 pubraw
000000 04 f8 04 f9 ea 79 7e 9b 07 89 e7 37 f2 76 c4 86
000010 16 17 f9 70 4e c4 67 ce 6e 64 ca 3a 5a bf 4d cb
000020 98 e1 11 0b 7a ec 40 f3 ea 32 d4 e9 6c 16 6e 14
000030 e3 77 15 1a 2e c2 81 a6 ed de f5 5c ed cb 10 26
000040 09
# (the >&/dev/null discards error messages because the contents of these fields are not ASN.1)
# (or you can omit it and just ignore the messages)
# openssl ec -text directly displays (all) the fields of the PEM file, 
# with the two you want in hex:
$ openssl ec <privpem -noout -text
read EC key
Private-Key: (256 bit)
ASN1 OID: secp256k1
# you can then postprocess this data as desired, 
# excluding the first line which is on stderr and not easily pipable, e.g.:
$ openssl ec <privpem -noout -text 2>/dev/null | sed -n 3,5p | tr -d ' :\n'; echo
$ openssl ec <privpem -noout -text 2>/dev/null | sed -n 7,11p | tr -d ' :\n'; echo
# given the _binary_ publickey, as from asn1parse above, 
# openssl can compute the address in _hex_ or binary 
# but not base58check (or bech32) as often wanted:
$ openssl sha256 <pubraw -binary | openssl ripemd160
(stdin)= 149a326797fdfd3790fba8f82571fd5f569341cc
# for binary output add -binary to the second subcommand,
# and redirect to a file >outfile because it isn't displayable

# by default openssl creates an EC key in uncompressed form, but you can specify, 
# or subsequently convert to, compressed; the asn1parse output depends on its input.
# The ec -text output can be converted in the same operation, e.g:
$ openssl ec <privpem -conv_form compressed -noout -text
read EC key
Private-Key: (256 bit)
ASN1 OID: secp256k1
# shows the compressed pubkey regardless of whether the file was compressed
# and now you would select lines 7-9 instead of 7-11.

Yes, the script generates keys safely as it uses renowned OpenSSL. Note that other factors besides the tool contribute to the safety of keys generation, e.g. air-gapped computer without viruses etc.

The keys are not output in Bitcoin Wallet Import Format (WIF), though. They need to be converted in order to be used in Bitcoin Wallets. There is the script for the converstion: https://gist.github.com/GregTonoski/438992249df6e4bd613f9758421ff38a

There is the Seed Tool to generate Bitcoin address: https://bitcoiner.guide/seed/ (look for the "Single Signature Address" section).

Your Answer

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

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