LION ATE MONK: Human-Readable Encryption Keys

Recovering a private key from a phrase

LION ATE MONK: Human-Readable Encryption Keys

Recovering a private key from a phrase

And so we create encryption keys, and then … wait for it … we protect them with a password. It is truly a crazy system to take a 128-bit encryption, and then apply a password which reduces the actual security of the key to just tens of bits. If there’s around 1 billion passwords possible, then the equivalent key size is just 30 bits, and which is easily crackable by a standard PC.

So, you have a cryptocurrency wallet, and it will have to support a private key, of which a public key can be automatically generated from it (using elliptic curve methods). And you are just ready to cash-out and now need your private key. But just as you are about to open your wallet, your computer crashes, and there’s nothing you can do to get your private key back. You have your public key, and ask security professionals if they can generate your private key from your public key, but they just shake their heads.

So you did manage to write the hex values of your key down, so you create a new wallet with the key, but it just doesn’t work. There’s something wrong with the way you wrote it down.

Well the solution is for us to write down a text form of your key— there are risks of course with this — and put it in a safe. But if it is in a hexadecimal, binary or Base64 format, there’s a good chance you will make a mistake in writing it down. For example a Bitcoin private key has 256 bits and thus uses 64 hex characters. We can thus use the method in RFC1751 to define “Human-Readable 128-bit Keys”. These map blocks into plain English. The following generates a random key, and converts it into an English-text phase:

Hex Key: 3829f07833beb425
Plain text key: ROB AVID ION CLAW TIDY EYE

And for a 128-bit key:

Hex Key: 1c7bb403682caa938bd98ecaa3d68c4e
Plain text key: HUG SKID ADD RISK OWNS AIDA GIRD RANT LORE ABET COCO MAO

And a 256-bit key:

Hex Key: 0988f4f832247fac733b9278ed59aeb0aac92522af6d296a5670450c90d2dd63
Plain text key: BUT ABET SPY CAST ABUT SAND DIME SINE IDLE SHOD HOSE BING LASS AFAR ACTS BRED ROSS LYRA BERG FLAW US KEN OAF LOLA

There is good separation between the words, and they could even be spoken over a telephone line (such as with out-of-band communications).

The standard defines 2,048 words, and where each defines 11 bits. For a 128-bit hex key, we generate 12 words (11x12=132 bits). Here are a few examples:

  • EB33 F77E E73D 4053 gives “TIDE ITCH SLOW REIN RULE MOT” (see RFC1751). Test
  • CCAC 2AED 5910 56BE 4F90 FD44 1C53 4766 gives “RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE” (see RFC1751). Test
  • 46be0927a4f86577f17ce6d10bc6aa61 gives “YAW TRUE AIDE AIDE FREE MIMI TURN TALE LUNG GUM COOL OW”. Test
  • 27de55aaa1af4ee040407ca0c7f652e9 gives “ ME USES COOL USE VIEW DAVE THY ASK MEN GREG CHAR DOLE”. Test

The following outlines the equivalent Python code:

The first few strings are:

char Wp[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",

Key expansion using RFC 5869

Increasingly we are using pass phrases instead of passwords, and where we can select words which make a phrase. Many cryptocurrency wallet methods now use this method in order to generate the protection on the wallet. An example is shown on the left-hand side provides 12 words in a sequence. These words can then be built into a phrase which can then be used to generate the encryption key which protects the wallet.

The method was created by Hugo Krawczyk and is standardised with RFC 5869. A important focus is that it will always produce the same key for the same input phrase. It was also published as a paper here.

Conclusions

The recreation of a private key is the ultimate fall-back, and you need to be sure there are strong security methods in place with the recovery. The advice for most, is that you shouldn’t keep your wallet on a networked attached computer, and should try and store on a physical device which connects using multi-factor security. But if you lose that device, a backup of the phrases used to recreate your private key, is a good dependable method.