Author

Topic: Extracting Privat Key from PEM File (Read 417 times)

HCP
legendary
Activity: 2086
Merit: 4361
January 20, 2021, 02:29:39 PM
#14
I'm not sure why you even want a .pem file? Huh No wallet in existence uses .pem files... and trying to extract keys from them is quite difficult and time consuming.

What are you actually trying to achieve? Huh The mass extraction of keys from a wallet.dat without requiring Bitcoin Core and/or the password? Huh

If you're just wanting to extract keys without having to load the wallet.dat into Bitcoin Core, then PyWallet is probably the best utility for just dumping keys straight from a wallet.dat (it even works with encrypted wallets). If you're trying to dump keys from encrypted wallet.dat files without knowing the password... well, that's just impossible. Undecided



With regards to PyWallet, I have a forked version of PyWallet that suppresses all the "KeyMeta" warnings (caused by updates to wallet.dat format since PyWallet was last updated) available here: https://github.com/HardCorePawn/pywallet

So, instead of hundreds of lines of:
Code:
"Wallet data not recognized: {'__type__': 'keymeta', '__value__':"............."
being output, they are just ignored... It is non-essential info if you're just after private keys etc anyway.

NOTE: Python 2 is required, will not work with Python 3.

Usage to dump the wallet:
Code:
python pywallet.py --dumpwallet --wallet=full\path\to\wallet.dat --passphrase=WALLETPASSPHRASE

for instance, if your wallet.dat was in E:\bitcoin, and encrypted with passphrase 'abc123', you'd use something like:
Code:
python pywallet.py --dumpwallet --wallet=E:\bitcoin\wallet.dat --passphrase=abc123
full member
Activity: 431
Merit: 105
January 19, 2021, 03:36:01 PM
#13
Hoi, because this is about btc, i have a wallet.dat, thought this private key came out of this mywallet.pfx from op,
strangly bc_key works with the wallet.dat
** Usage:

./bc_key BITCOIN_ADDRESS /path/to/wallet.dat
./bc_key ALL /path/to/wallet.dat
./bc_key EVERYTHING /path/to/wallet.dat

and op got his things out the pfx. as you said to have used it on an
address from a wallet?
But when I ran bc_key with an address in some wallet file, I got this output:

-----BEGIN EC PARAMETERS-----
short ASCII string                   for me here was btc address, but the thing is bc_key does work only with one wallet.dat i have unencrypted, that gives me the pem encrypted key back.
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
really long string of ASCII text that looks like one in OP       same here the encrypted key
-----END EC PRIVATE KEY-----

this make me think that this is a way around the loading the wallet inside the btc core client and then doing dumpwallet one by one, as op did one.
this above does all that in a jiffy with all addresses from bc_key back to pem and from there back to Wink your keys.
so every wallet is its own pem file.
the only pitty is that i dont know about is how to have a pem file with all the pem encrypted keys to get trough bc_key at one go.
seems it does not accept all those line at once without editing the result of bc_key, first of all the address is in the way, then one pem key it works and stops.
HCP
legendary
Activity: 2086
Merit: 4361
January 19, 2021, 01:47:14 PM
#12
the OP posted a pfx. wallet format. how to get a hold of that with btc.
Honestly, I've never seen a bitcoin wallet that uses the .pfx format... I'm not entirely sure that the OP even has a bitcoin private key. They seem to think they exported it from a mywallet.pfx file to .pem.

But in all the research I have done, I've only found reference to bitcoin and .pfx in a "presentation" here: https://github.com/Dreammaster13/blockchain-for-devs-book/blob/master/content/part-1-blockchain-networks-concepts/wallets/wallet-apis-and-libraries/wallets-apis-and-libraries.md#other-wallet-formats

Where it is mentioned as an "other" type of wallet/keystore Huh Undecided


Do you have a wallet.dat or a .pfx file? and what makes you think that the .pfx is a wallet file? Huh
full member
Activity: 431
Merit: 105
January 19, 2021, 07:11:21 AM
#11
Hi thanks for the help HCP,
this wallet was is not encrypted that is why i asked,
i know how to import it, so that was not an issue,
the OP posted a pfx. wallet format. how to get a hold of
that with btc.
HCP
legendary
Activity: 2086
Merit: 4361
January 18, 2021, 09:40:48 PM
#10
do you know if you can get to enter the password with bc_key for the wallet.dat file.
i get this error with bc_key, you might know why,

read EC key
unable to load Key
140245723776704:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: ANY PRIVATE KEY
bc_key doesn't work with "encrypted" wallet.dat files...


Quote
and this with ssl
openssl pkcs12 -in mywallet.dat -nocerts -out privatekey.pem -nodes
140391597541056:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1200:
140391597541056:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:374:Type=PKCS12
A standard "wallet.dat" (from Bitcoin Core) is not in a format that openssl can read/understand. A wallet.dat is a BerkeleyDB binary file... and if the wallet.dat has a password  on it, then the private key data will be encrypted.

If you have a wallet.dat, the best way to recover data from it is by opening a copy of the wallet.dat with a fully synced Bitcoin Core... attempting to open it with other utilities may damage the file or just not work.
full member
Activity: 431
Merit: 105
January 18, 2021, 08:37:28 PM
#9
From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?

I don't want to post my private Key online so anyone can take my BTC.  Roll Eyes

You are able to use a sample private key created from bitaddress.org if all you want to do is convert it from PEM and back again. https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html



PEM is an RSA private key file format. So you are trying to convert an RSA private key bytes to bitcoin private key bytes but this doesn't make sense at first because bitcoin private keys use elliptic curve cryptography, not RSA.

But when I ran bc_key with an address in some wallet file, I got this output:

-----BEGIN EC PARAMETERS-----
short ASCII string
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
really long string of ASCII text that looks like one in OP
-----END EC PRIVATE KEY-----

So what you did is convert the output of bc_key, an ECC private key, into an RSA public key. We should probably figure out how to get the private key bytes out of this ECC key first as it's most likely a valid bitcoin private key.


i get this error with bc_key, you might know why,

read EC key
unable to load Key
140245723776704:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: ANY PRIVATE KEY

and this with ssl
openssl pkcs12 -in mywallet.dat -nocerts -out privatekey.pem -nodes
140391597541056:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1200:
140391597541056:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:374:Type=PKCS12
full member
Activity: 431
Merit: 105
January 18, 2021, 08:01:29 PM
#8
From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?

I don't want to post my private Key online so anyone can take my BTC.  Roll Eyes

You are able to use a sample private key created from bitaddress.org if all you want to do is convert it from PEM and back again. https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html



PEM is an RSA private key file format. So you are trying to convert an RSA private key bytes to bitcoin private key bytes but this doesn't make sense at first because bitcoin private keys use elliptic curve cryptography, not RSA.

But when I ran bc_key with an address in some wallet file, I got this output:

-----BEGIN EC PARAMETERS-----
short ASCII string
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
really long string of ASCII text that looks like one in OP
-----END EC PRIVATE KEY-----

So what you did is convert the output of bc_key, an ECC private key, into an RSA public key. We should probably figure out how to get the private key bytes out of this ECC key first as it's most likely a valid bitcoin private key.


hi there arkadas,
do you know if you can get to enter the password with bc_key for the wallet.dat file.
thanks
full member
Activity: 431
Merit: 105
January 18, 2021, 07:54:57 PM
#7
From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?

I don't want to post my private Key online so anyone can take my BTC.  Roll Eyes


Thx for this code with Python HCP. This was what I need.

This gives an cool formated output to see everthing bedder:
Code:
openssl asn1parse -in privatekey.pem

Hex-dump is the Private Key

I found a Code from https://gist.github.com/Jun-Wang-2018/3105e29e0d61ecf88530c092199371a7#file-bitcoin_from_private_key_to_wif-py to convert HEX to WIF:

Code:
# From private key(hex) to Wallet Import Format(WIF)
# Reference: https://medium.freecodecamp.org/how-to-create-a-bitcoin-wallet-address-from-a-private-key-eca3ddd9c05f
#            https://docs.python.org/2/library/hashlib.html
import codecs  #If not installed: "pip3 install codecs"
import hashlib
# PK0 is a demo private key.
PK0 = "3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c"
PK1 = '80'+ PK0
PK2 = hashlib.sha256(codecs.decode(PK1, 'hex'))
PK3 = hashlib.sha256(PK2.digest())
checksum = codecs.encode(PK3.digest(), 'hex')[0:8]
PK4 = PK1 + str(checksum)[2:10]  #I know it looks wierd

# Define base58
def base58(address_hex):
    alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    b58_string = ''
    # Get the number of leading zeros
    leading_zeros = len(address_hex) - len(address_hex.lstrip('0'))
    # Convert hex to decimal
    address_int = int(address_hex, 16)
    # Append digits to the start of string
    while address_int > 0:
        digit = address_int % 58
        digit_char = alphabet[digit]
        b58_string = digit_char + b58_string
        address_int //= 58
    # Add ‘1’ for each 2 leading zeros
    ones = leading_zeros // 2
    for one in range(ones):
        b58_string = '1' + b58_string
    return b58_string

WIF = base58(PK4)
print(WIF)


quoted all dang,
here's the link: https://github.com/matja/bitcoin-tool
to say that matja btc tool does the same true one command and batch format like several keys at once. gl. Wink
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
January 17, 2021, 06:31:03 PM
#6
From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?

I don't want to post my private Key online so anyone can take my BTC.  Roll Eyes

You are able to use a sample private key created from bitaddress.org if all you want to do is convert it from PEM and back again. https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html



PEM is an RSA private key file format. So you are trying to convert an RSA private key bytes to bitcoin private key bytes but this doesn't make sense at first because bitcoin private keys use elliptic curve cryptography, not RSA.

But when I ran bc_key with an address in some wallet file, I got this output:

-----BEGIN EC PARAMETERS-----
short ASCII string
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
really long string of ASCII text that looks like one in OP
-----END EC PRIVATE KEY-----

So what you did is convert the output of bc_key, an ECC private key, into an RSA public key. We should probably figure out how to get the private key bytes out of this ECC key first as it's most likely a valid bitcoin private key.
HCP
legendary
Activity: 2086
Merit: 4361
January 17, 2021, 05:31:49 PM
#5
Just FYI, your code is Python 3 compatible only...
Code:
PK4 = PK1 + str(checksum)[2:10]  #I know it looks wierd

If you run that in Python2, it gives a really weird result as the str(checksum)[2:10] is only returning 6 chars instead of 8.

Instead of str() on the bytes object, you should probably use the .decode() method... so, a "better" solution might be:
Code:
# From private key(hex) to Wallet Import Format(WIF)
# Reference: https://medium.freecodecamp.org/how-to-create-a-bitcoin-wallet-address-from-a-private-key-eca3ddd9c05f
#            https://docs.python.org/2/library/hashlib.html
import codecs  #If not installed: "pip3 install codecs"
import hashlib
# PK0 is a demo private key.
PK0 = "3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c"
PK1 = '80'+ PK0
PK2 = hashlib.sha256(codecs.decode(PK1, 'hex'))
PK3 = hashlib.sha256(PK2.digest())
checksum_bytes = codecs.encode(PK3.digest(), 'hex')[0:8] #get checksum as bytes
checksum = checksum_bytes.decode("utf-8") #convert byte array to string
PK4 = PK1 + checksum

# Define base58
def base58(address_hex):
    alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    b58_string = ''
    # Get the number of leading zeros
    leading_zeros = len(address_hex) - len(address_hex.lstrip('0'))
    # Convert hex to decimal
    address_int = int(address_hex, 16)
    # Append digits to the start of string
    while address_int > 0:
        digit = address_int % 58
        digit_char = alphabet[digit]
        b58_string = digit_char + b58_string
        address_int //= 58
    # Add ‘1’ for each 2 leading zeros
    ones = leading_zeros // 2
    for one in range(ones):
        b58_string = '1' + b58_string
    return b58_string

WIF = base58(PK4)
print(WIF)

That should work on both Python2 and Python3 Wink
newbie
Activity: 3
Merit: 2
January 17, 2021, 02:23:15 PM
#4
From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?

I don't want to post my private Key online so anyone can take my BTC.  Roll Eyes


Thx for this code with Python HCP. This was what I need.

This gives an cool formated output to see everthing bedder:
Code:
openssl asn1parse -in privatekey.pem

Hex-dump is the Private Key

I found a Code from https://gist.github.com/Jun-Wang-2018/3105e29e0d61ecf88530c092199371a7#file-bitcoin_from_private_key_to_wif-py to convert HEX to WIF:

Code:
# From private key(hex) to Wallet Import Format(WIF)
# Reference: https://medium.freecodecamp.org/how-to-create-a-bitcoin-wallet-address-from-a-private-key-eca3ddd9c05f
#            https://docs.python.org/2/library/hashlib.html
import codecs  #If not installed: "pip3 install codecs"
import hashlib
# PK0 is a demo private key.
PK0 = "3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c"
PK1 = '80'+ PK0
PK2 = hashlib.sha256(codecs.decode(PK1, 'hex'))
PK3 = hashlib.sha256(PK2.digest())
checksum = codecs.encode(PK3.digest(), 'hex')[0:8]
PK4 = PK1 + str(checksum)[2:10]  #I know it looks wierd

# Define base58
def base58(address_hex):
    alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    b58_string = ''
    # Get the number of leading zeros
    leading_zeros = len(address_hex) - len(address_hex.lstrip('0'))
    # Convert hex to decimal
    address_int = int(address_hex, 16)
    # Append digits to the start of string
    while address_int > 0:
        digit = address_int % 58
        digit_char = alphabet[digit]
        b58_string = digit_char + b58_string
        address_int //= 58
    # Add ‘1’ for each 2 leading zeros
    ones = leading_zeros // 2
    for one in range(ones):
        b58_string = '1' + b58_string
    return b58_string

WIF = base58(PK4)
print(WIF)
HCP
legendary
Activity: 2086
Merit: 4361
January 15, 2021, 08:27:56 PM
#3
How can I do that with CMD and Editor? Is this the right way to get the correct bitcoin address?
I don't think you can... because the steps outlined in that post are for going from public key to address... not from the private key...

Also, it should be noted that (for the public key):
- http://blockexplorer.com/q/hashtoaddress no longer works... but you can use http://blockchain.info/q/hashtoaddress
- you only want the last 65 bytes from the output of the base64 -d command:

Code:
wget -O - -q http://blockchain.info/q/hashtoaddress/$(grep -v 'PUBLIC KEY' <<<"
-----BEGIN PUBLIC KEY-----
MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
/NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABJJ6TBhmiWm4
Y1ACBVJVn0oyG9Ay5IzEZq8cPyrs1PERl963YQh5UrGOT0NodynfHswkz8bUpaJW
FsowR/l9wXc=
-----END PUBLIC KEY-----" |
base64 -d |
tail -c 65 |
openssl dgst -sha256 |
cut -d\  -f2 |
xxd -r -p |
openssl dgst -rmd160 |
cut -d\  -f2)

This will return the example BTC address: 1Hy9dexzNzjvQYkYy6zKRVZMU8k2j5vuPt
So given a bitcoin address such as :
btc=1Hy9dexzNzjvQYkYy6zKRVZMU8k2j5vuPt


These commands only work on Linux... So you'll either need a Linux box, a Linux virtual machine, or you can even use "Windows Subsystem for Linux"...




As for your situation of having a private key .pem file...

Theoretically, you should probably be able to decode the private key from the .pem file output in a similar fashion... but you'd need to know exactly which parts of the Base64 encoded text were actually the hex private key (like how you only want the last 65 bytes of the "base64 -d" command above to get the public key from the .pem file.)

Looking at this post on StackExchange: https://bitcoin.stackexchange.com/questions/66594/signing-transaction-with-ssl-private-key-to-pem

We can see that if you can find the byte sequence: "30740201010420" in the decoded base64 output... then the next 32 bytes (64 chars) should be the HEX private key... from that stack exchange post, we can see the example hex private key they started with was:
Code:
3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c

And the privkey.pem is:
Code:
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----


If we use Python... we can decode that and view the bytes in "hex":
Code:
hardcorepawn@HardCorePC:~/$ python
Python 2.7.17 (default, Jul 20 2020, 15:37:01)
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> import binascii
>>> base64_message = "MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAKoUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw=="
>>> message_bytes = base64.b64decode(base64_message)
>>> binascii.hexlify(message_bytes)
'307402010104203cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2ca00706052b8104000aa14403420004bf350d2821375158a608b51e3e898e507fe47f2d2e8c774de4a9a7edecf74eda24243cb992c5673a07fa5b3a66cd8e3acef2809d0e380a0c7929dab1e5d5438b'

From this we can see the decoded Base64 is:
Code:
307402010104203cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2ca00706052b8104000aa14403420004bf350d2821375158a608b51e3e898e507fe47f2d2e8c774de4a9a7edecf74eda24243cb992c5673a07fa5b3a66cd8e3acef2809d0e380a0c7929dab1e5d5438b

We can see the sequence "30740201010420" right at the start (highlighted "Red")... so the next 32 bytes (64 chars) (highlighted "orange") should be the hex private key:
Quote
307402010104203cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2ca00706052b8104000aa14403420004bf350d2821375158a608b51e3e898e507fe47f2d2e8c774de 4a9a7edecf74eda24243cb992c5673a07fa5b3a66cd8e3acef2809d0e380a0c7929dab1e5d5438b

Giving us a hex private key of:
Code:
3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c

Which matches the HEX private key the example started with! Smiley


So, try base64 decoding your .pem file contents... and see if you can find the sequence "30740201010420"... if you can, the next 32 bytes (64 chars) should be the private key.

Let me know if you need any help.
full member
Activity: 260
Merit: 129
January 15, 2021, 05:32:20 PM
#2

-----BEGIN PRIVATE KEY-----
MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
/NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABJJ6TBhmiWm4
Y1ACBVJVn0oyG9Ay5IzEZq8cPyrs1PERl963YQh5UrGOT0NodynfHswkz8bUpaJW
FsowR/l9wXc=
-----END PRIVATE KEY-----



From the old topic it's a PUBLIC key not a PRIVATE key. Why did you change it?
newbie
Activity: 3
Merit: 2
January 15, 2021, 08:48:40 AM
#1
Hello there,

I have a problem with extracting an Privat Key from an old wallet (*.pfx).

In 2011 I convert a Wallet in this (OpenSSL PEM) format. In an old Post i can see the answer, but my programming skill is weak: https://bitcointalksearch.org/topic/50-btc-bounty-for-a-pem-public-key-to-bitcoin-address-convertor-2631

1. I use OpenSSL for receiving the Privat Key:
openssl pkcs12 -in mywallet.pfx -nocerts -out privatekey.pem -nodes

2. Open the *.pem (I used the public key from the Topic above  Wink ):
-----BEGIN PRIVATE KEY-----
MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
/NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABJJ6TBhmiWm4
Y1ACBVJVn0oyG9Ay5IzEZq8cPyrs1PERl963YQh5UrGOT0NodynfHswkz8bUpaJW
FsowR/l9wXc=
-----END PRIVATE KEY-----


As I understand it, I have to do the following steps :

- computes the sha256 of the key ;
- computes the rmd160 of this hash ;
- add a byte at the begin for the version number (?) ;
- add four bytes at the end for the check sum ;
- encode the result in base58 ;


How can I do that with CMD and Editor? Is this the right way to get the correct bitcoin address?

Thanks for help.
Jump to: