给定曲线和私有指数创建 ECDSA 私钥? [英] Creation of ECDSA private key given curve and private exponent?

查看:93
本文介绍了给定曲线和私有指数创建 ECDSA 私钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 cryptopp 的新手,并且一直在努力创建用于 ECDSA 签名的私钥.

I am new to cryptopp and have been struggling for a while with the creation of private keys for ECDSA signing.

我有一个十六进制编码的私有指数 E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB.这被存储为一个字符串.

I have a hex encoded private exponent E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB. This is stored as a string.

我想用它来签署一个使用 ECDSA 的文本块.我的代码看起来有点像这样

I want to use this to sign a text block using ECDSA. My code looks a bit like this

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;
}

当我尝试执行 privateKey.load(...) 时,此代码在 Visual Studio 中生成以下错误

This code generates the following error in Visual studio on the when I try to do 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.

我猜我在做一些愚蠢的事情......任何帮助都会很棒???

I am guessing I am doing something a bit stupid... any help would be great???

PS 我在使用 ECDH 生成 GMAC 时遇到了类似的问题,但通过将密钥保存为 SECByteBlock 解决了这个问题,但这个技巧"在这种情况下似乎不起作用.

PS I had a similar issue using ECDH for GMAC generation but got round this by saving the key as a SECByteBlock but this 'trick' doesnt seem to work in this case.

推荐答案

DLLTest.exe:Microsoft C++ 异常:CryptoPP::BERDecodeErr ...

DLLTest.exe: Microsoft C++ exception: CryptoPP::BERDecodeErr ...

您有一个私有指数,而没有一个私有密钥.所以你应该不要在它上面调用Load.这导致了 Crypto++ BERDecodeErr 异常.

You have a private exponent, and not a private key. So you should not call Load on it. That's causing the Crypto++ BERDecodeErr exception.

答案在 ECDSA wiki 页面 中有详细说明,但并不明显.您需要执行以下操作来初始化给定曲线和指数的 privateKey::

The answer is detailed on the ECDSA wiki page, but its not readily apparent. You need to perform the following to initialize the privateKey given the curve and exponent::

string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
exp.insert(0, "0x");

Integer x(exp.c_str());
privateKey.Initialize(ASN1::secp256r1(), x);

前置 "0x" 确保 Integer 类将正确解析 ASCII 字符串.您还可以将 "h" 字符附加到字符串.您可以在 Integer.cpp<查看 Integer 类的解析代码/a> 在 StringToInteger 函数中的第 2960 行附近.

Prepending the "0x" ensures the Integer class will parse the ASCII string correctly. You can also append a "h" character to the string. You can see the parsing code for Integer class at Integer.cpp around line 2960 in the StringToInteger function.

这是做同样事情的另一种方式:

Here's another way to do the same thing:

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 使用它的 解码(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED) 方法.

The HexDecoder will perform the ASCII to binary conversion for you. The buffer held by the HexDecoder will then be consumed by the Integer using its Decode (BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED) method.

这是使用 HexDecoder 的另一种方法(Crypto++ 是有时像脚本语言一样糟糕:)...

And here is another way using HexDecoder (Crypto++ is as bad as scripting languages at times :)...

string exp = "E4A6CFB431471CFCAE491FD566D19C87082CF9FA7722D7FA24B2B3F5669DBEFB";
StringSource ss(exp, true /*punpAll*/, new HexDecoder);

Integer x;
x.Decode(ss, ss.MaxRetrievable());

privateKey.Initialize(ASN1::secp256r1(), x);

<小时>

初始化密钥后,您应该对其进行验证:


After initializing the key, you should validate it:

bool result = privateKey.Validate( prng, 3 );
if( !result ) { /* Handle error */ }

<小时>

这将输出二进制数据:


This will output binary data:

cout << signature.data() << endl;

如果您想要一些可打印/可读的东西,请通过 Crypto++ HexEncoder 运行它.

If you want something printable/readable, run it though a Crypto++ HexEncoder.

这篇关于给定曲线和私有指数创建 ECDSA 私钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆