bitcoinjs / bip38

BIP38 is a standard process to encrypt Bitcoin and crypto currency private keys that is less susceptible to brute force attacks thus protecting the user.
http://cryptocoinjs.com/modules/currency/bip38/
MIT License
206 stars 100 forks source link

Get encrypted private key from mnemonic for decryption? #63

Closed kaloudis closed 4 years ago

kaloudis commented 4 years ago

Hey all,

First time really get my hands dirty with bitcoinjs-lib and related libraries. I'm working with a BIP39 mnemonic and a BIP38 passphrase for it. I'm not quite sure how to get the private key in the right format for the bip38.decrypt() function

const bip32 = require('bip32');
const bip38 = require('bip38');
const bip39 = require('bip39');
const bitcoin = require('bitcoinjs-lib');

const mnemonic = 'redacted mnemonic';
const passphrase = 'redacted passphrase';

const seedBuffer = bip39.mnemonicToSeedSync(mnemonic);
const root = bip32.fromSeed(seedBuffer);

// none of the following values work as encryptedPrivKey in bip38.decrypt()
const encryptedPrivKey = root.toBase58();
// encryptedPrivKey
// root.privateKey
// root.toWIF()
// seedBuffer

const privateKeyWif = bip38.decrypt(encryptedPrivKey, passphrase, function (status) {
  console.log(status.percent)
});

Apologies if this question is better suited for one of the other repos.

lukechilds commented 4 years ago

Can you clarify what the variable passphrase is?

I think you may be getting confused between a BIP39 passphrase (to combine with a BIP39 mnemonic) and a BIP38 passphrase (to decrypt a BIP38 encrypted private key).

lukechilds commented 4 years ago

If it's a passphrase for your mnemonic (BIP39), which I'm assuming is what it is, then you don't need BIP38, just do:

const bip39 = require('bip39');
const bip32 = require('bip32');

const mnemonic = "much bottom such hurt hunt welcome cushion erosion pulse admit name deer"
const passphrase = "password1";

const seed = bip39.mnemonicToSeedSync(mnemonic, passphrase);
const node = bip32.fromSeed(seed);
node.derivePath("m/44'/0'/0'/0/0").toWIF();
// "KxZFVjWvGqCvtKowcps9TusBrSa1zkUpBTFkoNiLYhxcTnrAC9n7"

You can enter that mnemonic/passphrase on https://iancoleman.io/bip39/ and you'll see the private key for the m/44'/0'/0'/0/0 address is the same.

If I've assumed incorrectly and you really do want to use BIP38 then you need to generate a keypair normally first, then encrypt the private key with BIP38, then use your passphrase to decrypt it in the future.

kaloudis commented 4 years ago

Works like a charm. Thank @lukechilds!