How to use a coldcard MK3 to derive your new account password from a 24 word seed
Each hive account has four keys which can be used to sign broadcast operations. As the key name says (owner key, active key, posting key), they have different use cases. Normally, a single password is used to derive these four keys from it. This has the advantage that only one passphrase needs to be securely stored.
I can change my account keys by generating a new password:
![New Password](https://images.hive.blog/DQmWagwVQs2GsJFQMMFpQCbLFSWxKS5jmDK5WYsfNAC6tkq/New%20Password)
You need to `BACK IT UP BY STORING IN YOUR PASSWORD MANAGER OR A TEXT FILE.`, but what happens when your hard drive is failing or your password manager (lost the master password, ...)? You can print it, but what happens in case of a fire or water damage?
## Using your bitcoin seed for Hive
When you have stored your bitcoin seed (consisting normally of 24 words) in metal, it would be great if you could use this also to store your Hive password.
It is possible to use [BIP-85 (Deterministic Entropy From BIP32 Keychains)](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki) for creating a new password for a hive account using a coldcard mk3 hardware wallet (As far as I know this is the only device that support BIP85).
![coldcard](https://images.hive.blog/DQmYZebd2XQzeyxR2LhQEuiCmvAZpweC1ywThuBnkmAtHVb/coldcard)
When I use the derived WIF to create a new Password for my Hive account, I do not need to store my Hive keys and Password anymore, as they can be recreated from the securely stored bitcoin seed (I need to remember the used index number, or I need to try all possible numbers from 0 to 9999).
Thus I can increase my account security when I do not store the password and the owner key in my computer.
## How to use the coldcard mk3 to create a new Password for Hive
This guide will use the [coldcard mk3](https://coldcardwallet.com/) which has the necessary bip-85 support and python (beem) for generating and changing the account keys.
### Storing a WIF on a sdcard
At first we use the coldcard to derive a new WIF and store it on a sdcard.
![Go to Advanced](https://images.hive.blog/DQmUJxn6RzUbxNrXMMkP6PnT1UTMQC4kbHe6Ad1PYLiFyqD/Go%20to%20Advanced)
![Then to Derive Entropy](https://images.hive.blog/DQmVjNSAtvVtuiDPnM4u91D8VypYkdhx1UeVsooFzkhSFVs/Then%20to%20Derive%20Entropy)
We need to select WIF:
![Then to WIF](https://images.hive.blog/DQmSn5u2kBPRsf7V5EiM2VrUSdKgS7VDQhkJjJCte8ZDS3f/Then%20to%20WIF)
Select a number you can remember:
![Select a number](https://images.hive.blog/DQmRrywjVhNWgscazDfVV9f1UrmVZKhpU1R9xj6xEjN7DT4/Select%20a%20number)
Store the WIF to the MicroSD:
![Press 1 to store the WIF on the sd card](https://images.hive.blog/DQmQiWagr6YLFoPCjrBBptJqGAhP5GP5ZzbGomEio1xYfAa/Press%201%20to%20store%20the%20WIF%20on%20the%20sd%20card)
## Reading the WIF from the sdcard and change the HIVE keys
We need the following python packages:
```
pip3 install beem
```
The WIF from the coldcard needs firstly converted into a HIVE WIF and then a password is derived by applying `PasswordKey` to it and adding a `P`:
```
from beemgraphenebase.account import PrivateKey, PasswordKey
WIF="xxx" # from coldcard
wif = PrivateKey(WIF)
pk = PasswordKey("", str(wif), role="")
password = 'P' + str(pk.get_private())
print(password)
```
`password` is the new account password that can be set in `https://wallet.hive.blog/@/password`
After changing the account password, the new posting, active and memo key should be stored and the Password and the WIF on the sdcard should be deleted.
Whenever, an account key is getting lost or when the owner key is needed,
it can be created from the derive WIF which is created by the coldcard.
It is also possible to automate everything. The following script will
* Read the sdcard and extract the WIF
* Create a new Password for the account
* Change the account password by broadcasting `update_account`
```
from beem import Hive
from beemgraphenebase.account import PrivateKey, PasswordKey
import argparse
from prettytable import PrettyTable
import sys
import getpass
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Derives a new password from a coldcard WIF")
parser.add_argument('wiffile', type=str, nargs='?',
help='colcard wif key file to read.')
parser.add_argument('account', type=str, nargs='?',
help='account name.')
args = parser.parse_args()
wiffile = args.wiffile
account = args.account
next_var = ""
wif = ""
path = ""
with open(wiffile) as fp:
for line in fp:
if line.strip() == "":
continue
if line.strip() == "WIF (privkey):":
next_var = "wif"
continue
elif "Path Used" in line.strip():
next_var = "path"
continue
if next_var == "wif":
wif = line.strip()
elif next_var == "path":
path = line
next_var = ""
wif = PrivateKey(wif)
pk = PasswordKey("", str(wif), role="")
password = 'P' + str(pk.get_private())
owner_key = PasswordKey(account, password, role="owner")
owner_pubkey = format(owner_key.get_public_key(), "STM")
active_key = PasswordKey(account, password, role="active")
active_pubkey = format(active_key.get_public_key(), "STM")
posting_key = PasswordKey(account, password, role="posting")
posting_pubkey = format(posting_key.get_public_key(), "STM")
memo_key = PasswordKey(account, password, role="memo")
memo_pubkey = format(memo_key.get_public_key(), "STM")
t = PrettyTable(["Key", "Value"])
t.align = "l"
t.add_row(["Account", account])
t.add_row(["Path", path])
t.add_row(["New owner pubkey", owner_pubkey])
t.add_row(["New active pubkey", active_pubkey])
t.add_row(["New posting pubkey", posting_pubkey])
t.add_row(["New memo pubkey", memo_pubkey])
print(t)
ret = input("Broadcast update_account with new keys? [y/n]")
if ret in ["y", "yes"]:
owner_key = getpass.getpass(prompt="current owner key:")
hive = Hive(keys=[owner_key])
tx = hive.update_account(account, owner_key=owner_pubkey, active_key=active_pubkey,
posting_key=posting_pubkey, memo_key=memo_pubkey)
print(tx)
ret = input("Show private keys? [y/n]")
if ret in ["y", "yes"]:
t = PrettyTable(["Key", "Value"])
t.align = "l"
t.add_row(["active privkey", str(active_key.get_private_key())])
t.add_row(["posting privkey", str(posting_key.get_private_key())])
t.add_row(["memo privkey", str(memo_key.get_private_key())])
print(t)
ret = input("Show owner key and password? [y/n]")
if ret in ["y", "yes"]:
t = PrettyTable(["Key", "Value"])
t.align = "l"
t.add_row(["owner privkey", str(owner_key.get_private_key())])
t.add_row(["Password", str(password)])
print(t)
del owner_key
del memo_key
del posting_key
del active_key
del password
```
This needs to be stored as py file (e.g. new_password.py) and can then be called:
```
python3 new_password.py F:\drv-wif-idx0.txt holger80
```
where `F:\drv-wif-idx0.txt` is the path to the exported WIF file.
Deleting the WIF text file on the sdcard needs to be done by hand (remember to store the used index number).
I'm currently adding this also to beempy, the CLI tool in beem.
There is also a second way in creating a new password from a seed using hardware wallet (signing a message), which I'm investigating right now.
___
*If you like what I do, consider casting a vote for me as witness on [Hivesigner](https://hivesigner.com/sign/account-witness-vote?witness=holger80&approve=1) or on [PeakD](https://peakd.com/witnesses)*</div>
See: How to use a coldcard MK3 to derive your new account password from a 24 word seed by @holger80