我是新到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我在GMAC一代中使用ECDH时遇到了类似的问题,但是通过将密钥保存为SECByteBlock解决了这个问题,但是这个“技巧”在这种情况下似乎不起作用。
对于以后寻找此内容的其他人
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;
}
DLLTest.exe: Microsoft C异常:CryptoPP::berdecoderer...
您有一个私有指数,但没有私钥。因此您不应该对它调用< code>Load。这导致了Crypto < code > berdecoderer 异常。
答案在ECDSA wiki页面上有详细说明,但不是很明显。给定曲线和指数,您需要执行以下操作来初始化privateKey
::
string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
exp.insert(0, "0x");
Integer x(exp.c_str());
privateKey.Initialize(ASN1::secp256r1(), x);
将"0x"
放在前面可确保Intger
类将正确解析ASCII字符串。您还可以将"h"
字符附加到字符串。您可以在StringToIntger
函数的第2960行周围的Integer.cpp处看到intger
类的解析代码。
下面是另一种做同样事情的方法:
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
持有的缓冲区将被整数
使用其Decode(BufferedTransform
这是使用
HexDecoder
的另一种方法(加密有时与脚本语言一样糟糕,:)......
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运行它。
我正在努力从公钥的字符串表示创建ECDSA公钥,即 以前我发现我必须给这个键加上前缀' 04 ',所以不确定这次是否需要这样做? 我正在尝试生成它以用于验证签名 其中要签名的数据是 我现在的粗略代码如下 这是切碎在一起的,所以不能建造。任何帮助都很好 PS我在这里问了一个类似的关于私钥的问题给定曲线和私钥指数的ECDSA私钥的创建?
我也尝试了npm ursa模块,不幸的是没有成功。
我正在尝试用c#签署比特币交易。我有两段代码要完成。我可以使用Bouncy castle创建一组私钥和公钥。我可以将其转换为钱包导入格式ok。 我还可以从ECDSA公钥生成比特币地址。 然而,我想签署一项交易,我所拥有的只是我的私钥。我不想把东西放进钱包里签名。那么,在只提供私钥的情况下,如何生成公钥呢? 我发现了一个javascript方法可以做到这一点: 我在充气城堡看到的唯一方法是生成随机一
我是Openssl的新手,我已经生成了私钥myprivatekey。pem和公钥mypublickey。pem与: 和我的公钥: 接下来我想做的是用通行短语私钥加密我的ecdsa,并对我的公钥进行认证请求,感谢大家的帮助。
我一直在阅读一些RSA文献和堆栈溢出问题,但我没有得到明确的答案。 仅给定一个RSA私钥模和私钥指数,这是我所拥有的全部(也足够用于所有密码相关操作),我能得到相关的公钥模和公钥指数吗? 另外,我是否可以仅用这两个参数获得私钥的编码形式?我在java中尝试了以下方法(java不是实际的请求),但是支持它的OpenSSL引擎失败,错误为:04000090:RSA例程:openSSL_internal
问题内容: 我试图从私钥生成公共ECDSA密钥,但是在Internet上如何进行此操作方面,我还没有找到太多帮助。几乎所有内容都是根据公共密钥规范生成公共密钥的,我不知道该如何获得。到目前为止,这是我汇总的内容: 但是,在运行时,出现以下错误: 我究竟做错了什么?有没有更好/更简便的方法可以做到这一点? 编辑:我设法获得一些代码进行编译,但不能正常工作: 当我运行它时,它会生成一个publicKe