创建给定曲线和私有指数的ECDSA私钥
Creation of ECDSA private key given curve and private exponent?
我是cryptopp的新手,并且一直在为ECDSA签名创建私钥而苦苦挣扎。
我有一个十六进制编码的私人指数E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB
.这存储为字符串。
我想使用它来使用 ECDSA 对文本块进行签名。 我的代码看起来有点像这样
string Sig::genSignature(const string& privKeyIn, const string& messageIn)
{
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::PrivateKey privateKey;
privateKey.AccessGroupParameters().Initialize(ASN1::secp256r1());
privateKey.Load(StringSource(privKeyIn, true, NULL).Ref());
ECDSA<ECP, SHA256>::Signer signer(privateKey);
// Determine maximum size, allocate a string with that size
size_t siglen = signer.MaxSignatureLength();
string signature(siglen, 0x00);
// Sign, and trim signature to actual size
siglen = signer.SignMessage(prng, (const byte *) messageIn.data(), (size_t) messageIn.length(), (byte*)signature.data());
signature.resize(siglen);
cout << signature.data() << endl;
return signature;
}
此代码在Visual studio中生成以下错误,当我尝试执行privateKey.load(...(
First-chance exception at 0x7693C42D in DLLTest.exe: Microsoft C++ exception: CryptoPP::BERDecodeErr at memory location 0x0033EEA8.
Unhandled exception at 0x7693C42D in DLLTest.exe: Microsoft C++ exception: CryptoPP::BERDecodeErr at memory location 0x0033EEA8.
我猜我正在做一些愚蠢的事情...任何帮助都会很棒???
PS 我在使用 ECDH 生成 GMAC 时遇到了类似的问题,但通过将密钥保存为 SECByteBlock 来解决这个问题,但在这种情况下,这个"技巧"似乎不起作用。
DLLTest.exe: Microsoft C++ exception: CryptoPP::BERDecodeErr ...
您有一个私有指数,而不是私钥。所以你不应该打电话给Load
。这导致了Crypto++BERDecodeErr
异常。
答案在ECDSA维基页面上有详细说明,但并不明显。您需要执行以下操作来初始化给定曲线和指数的privateKey
:
string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
exp.insert(0, "0x");
Integer x(exp.c_str());
privateKey.Initialize(ASN1::secp256r1(), x);
在"0x"
前面加上前缀可确保Integer
类将正确分析 ASCII 字符串。还可以将"h"
字符追加到字符串中。您可以在 Integer 处看到Integer
类的解析代码.cpp在 StringToInteger
函数的第 2960 行附近。
这是执行相同操作的另一种方法:
string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
HexDecoder decoder;
decoder.Put((byte*)exp.data(), exp.size());
decoder.MessageEnd();
Integer x;
x.Decode(decoder, decoder.MaxRetrievable());
privateKey.Initialize(ASN1::secp256r1(), x);
HexDecoder
将为您执行 ASCII 到二进制的转换。然后,HexDecoder
持有的缓冲区将由Integer
使用其Decode (BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED)
方法使用。
这是使用HexDecoder
的另一种方法(Crypto++有时与脚本语言一样糟糕:)...
string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
StringSource ss(exp, true /*punpAll*/, new HexDecoder);
Integer x;
x.Decode(ss, ss.MaxRetrievable());
privateKey.Initialize(ASN1::secp256r1(), x);
初始化密钥后,应对其进行验证:
bool result = privateKey.Validate( prng, 3 );
if( !result ) { /* Handle error */ }
这将输出二进制数据:
cout << signature.data() << endl;
如果你想要一些可打印/可读的东西,通过Crypto++ HexEncoder运行它。
供以后寻找的其他人使用
string genSignature(const string& privKeyIn, const string& messageIn)
{
CryptoPP::Integer secretNumber(genSecretNumber(privKeyIn, messageIn));
AutoSeededRandomPool secretNumberGenerator;
if (encryptBase::debug)
{
cout << "secret number: " << secretNumber << endl;
}
SecByteBlock message(convertHexStrToSecByteBlock(messageIn));
ECDSA<ECP, SHA256>::PrivateKey privateKey;
string exp(privKeyIn);
exp.insert(0, "0x");
Integer x(exp.c_str());
privateKey.Initialize(ASN1::secp256r1(), x);
AutoSeededRandomPool prng;
if (!privateKey.Validate(prng, 3))
{
cout << "unable to verify key" << endl;
return "failed to verify key";
}
ECDSA<ECP, SHA256>::Signer signer(privateKey);
size_t siglen = signer.MaxSignatureLength();
string signature(siglen, 0x00);
siglen = signer.SignMessage(secretNumberGenerator, message.BytePtr(), message.size(), (byte*)signature.data());
signature.resize(siglen);
string encoded;
HexEncoder encoder;
encoder.Put((byte *) signature.data(), signature.size());
encoder.MessageEnd();
word64 size = encoder.MaxRetrievable();
if (size)
{
encoded.resize(size);
encoder.Get((byte*)encoded.data(), encoded.size());
}
return encoded;
}
- 使用简单类型列表实现的指数编译时间.为什么
- 如何从组合指数中找到仓位
- 正在读取 obj 文件!(指数)
- C++:快速模块化指数
- 在C++不使用 POW 的情况下处理负指数
- 比较向量中的元素时所花费的时间呈指数级增长
- 如何将包含指数的 QString 转换为C++中的双倍?
- 将数字提高到一个巨大的指数
- 负指数是否必然意味着未定义的行为
- 整数的指数速记
- 在矩阵逆变器上工作,由于某种原因,我的指数循环不起作用
- 自定义提升多精度指数中的位数
- 如何计算复矩阵的指数
- 用C++打印指数形式的素数分解
- 为什么Regex(c++)需要指数时间
- 指数近似不适合小输入或大输入
- 在加密++中使用ECDSA的正确方法是什么?
- ECDSA 密钥对生成输出错误
- 如果 std::numeric_limits<float>::is_iec559 为真,这是否意味着我可以以明确定义的方式提取指数和尾数?
- 创建给定曲线和私有指数的ECDSA私钥