我使用bip39.generateMnemonic();
生成助记符。我需要用secp256k1将此助记符转换为AsymmetricKeyPair。
AsymmetricKeyPair<PublicKey, PrivateKey> secp256k1KeyPair() {
var keyParams = ECKeyGeneratorParameters(ECCurve_secp256k1());
var mnemonic = getMnemonic();
var seed = bip39.mnemonicToSeed(mnemonic);
print('mnemonicToSeed=========$seed');
var random = FortunaRandom();
random.seed(KeyParameter(seed));
var generator = ECKeyGenerator();
generator.init(ParametersWithRandom(keyParams,random));
return generator.generateKeyPair();
}
getMnemonic() {
var mnemonic = bip39.generateMnemonic();
print('mnemonic=========$mnemonic');
return mnemonic;
}
字符串
未处理异常:无效参数:福图纳PRNG只能使用256位密钥。
最后我可以生成AsymmetricKeyPair如下。但我不确定我是否以正确的方式做了它。如果我错了请纠正我。
/// generates dynamic mnemonic
String getMnemonic() {
var mnemonic = bip39.generateMnemonic();
print('mnemonic=========$mnemonic');
return mnemonic;
}
AsymmetricKeyPair<PublicKey, PrivateKey> secp256k1KeyPair() {
var keyParams = ECKeyGeneratorParameters(ECCurve_secp256k1());
var mnemonic = getMnemonic();
var seed = bip39.mnemonicToSeed(mnemonic);
final digest = sha256.convert(seed); // 32 bytes
print('mnemonicToSeed=========$seed');
var random = FortunaRandom();
random.seed(KeyParameter(_seed(digest.bytes)));
var generator = ECKeyGenerator();
generator.init(ParametersWithRandom(keyParams,random));
return generator.generateKeyPair();
}
Uint8List _seed(List<int> digest) {
var seed = List<int>.generate(digest.length, (_) => digest[_]);
return Uint8List.fromList(seed);
}
型
由于FortunaRandom不是强大的,你能建议其他的吗?
2条答案
按热度按时间4ktjp1zp1#
如果我查看代码,那么BIPS 39的
mnemonicToSeed
将生成512位输出(PBKDF 2的输出大小,更多信息here)。你可以只使用最左边的位/字节,取256位。Ye old福图纳在计数器模式下使用块密码,并且可能初始种子大小必须与(或)密钥大小相同。请注意,我不知道你想做什么。如果我尝试确定性地生成另一个密钥对,我不会使用您的代码,因为它依赖于实现。如果
generateKeyPair
中有任何变化,例如如果使用不同的方法来提取随机字节,那么它将中断,而API将保持不变。对于具有secp256k1
的椭圆曲线,这种可能性并不高,因为密钥对生成在很大程度上也是确定性的,但是突然生成错误的私钥肯定会产生可怕的后果。trnvg8h32#
为了避免使用PRNG(例如
FortunaRandom
),您可以应用以下方法:在导出原始32字节私钥(通过
getMnemonic()
和mnemonicToSeed()
)后,可以直接使用ECPrivateKey()
导入。原始公钥通过与生成点相乘并随后导入
ECPublicKey()
得到:字符串