BIP38提出了一个通用标准,使用一个口令对私钥加密并使用Base58Check对加密的私钥进行编码,这样加密的私钥就可以安全地保存在备份介质里,安全地在钱包间传输,保持密钥在任何可能被暴露情况下的安全性。避免明文私钥暴露遭受损失,这种方法常用于纸钱包(和“实物比特币”)。这个加密标准使用了AES,这个标准由NIST建立,并广泛应用于商业和军事应用的数据加密。
BIP38加密方案是:输入一个比特币私钥,通常使用WIF编码过,base58chek字符串的前缀“5”。此外还需要一个长密码作为口令,通常由多个单词或一段复杂的数字字母字符串组成。BIP38加密方案的结果是一个由base58check编码过的加密私钥,前缀为6P。如果你看到一个6P开头的的密钥,这就意味着该密钥是被加密过,并需要一个口令来转换(解码)该密钥回到可被用在任何钱包WIF格式的私钥(前缀为5)。许多钱包APP现在能够识别BIP38加密过的私钥,会要求用户提供口令解码并导入密钥。第三方APP,诸如非常好用基于浏览器的Bit Address,可以被用来解码BIP38的密钥。
最通常使用BIP38加密的密钥用例是纸钱包——一张纸张上备份私钥。只要用户选择了强口令,使用BIP38加密的私钥的纸钱包就无比的安全,这也是一种很棒的比特币离线存储方式(也被称作“冷存储”)。
public void bip38_noCompression_noEcMultiply_test() throws Exception {
//如果你看到一个6P开头的的密钥,这就意味着该密钥是被加密过;输入生成一个加密私钥对象
BIP38PrivateKey encryptedKey = BIP38PrivateKey.fromBase58(MAINNET,
"6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg");
//用密码解密,长密码作为口令,通常由多个单词或一段复杂的数字字母字符串组成
ECKey key = encryptedKey.decrypt("TestingOneTwoThree");
//生成转储私钥对象
DumpedPrivateKey dumpedPrivateKey=key.getPrivateKeyEncoded(MAINNET);
String privateKey= dumpedPrivateKey.toString();
//该密钥回到可被用在任何钱包WIF格式的私钥(前缀为5)
assertEquals("5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR",
privateKey);
}