创建ECDSA公共密钥给定曲线和公共点? [英] Creation of ECDSA public key given curve and public point?

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

问题描述



 字符串devicePublicKey(())公共密钥创建ECDSA公钥86FB5EB3CA0507226BE7197058B9EC041D3A3758D9D9C91902ACA3391F4E58AEF13AFF63CC4EF68942B9B94904DC1B890EDBEABD16B992110624968E894E560E); 

之前我发现我必须在'04'前加上这个键,所以不确定这是否需要这是什么时候?



我试图生成它用于验证签名

 串ecs04b2ExpSignature( 0199E984CEC75DDCA7F1DDF6E53E2E67352A2BE38A4B66F8ED596606FAB983FF300CAA76DE88CED9D563A5C03E8F3A7C000780F3F2061C611E9AA0B18B460D77); 

其中要签名的数据是

  string ecs04b2SigningData(020000000000000001FFFFFFFFFFFFFFFE123456789ABCDEF000B3DA2000000100000300000003030003000300); 

现在我的粗略代码看起来像这样

  SecByteBlock消息(convertHexStrToSecByteBlock(messageIn)); 
SecByteBlock签名(convertHexStrToSecByteBlock(signatureIn));

ECDSA< ECP,SHA256> :: PublicKey publicKey;
string inPublicKey(04);
inPublicKey.append(pubKeyIn);
SecByteBlock pubKey = encryptBase :: convertHexStrToSecByteBlock(inPublicKey);



ECP :: Point p;
publicKey.AccessGroupParameters()。Initialize(CryptoPP :: ASN1 :: secp256r1());
publicKey.GetGroupParameters()。GetCurve()。DecodePoint(p,pubKey,publicKey.GetGroupParameters()。GetCurve()。EncodedPointSize(true));
publicKey.SetPublicElement(p);

// ByteQueue qt;
//qt.Put((byte*)exp.c_str(),(size_t)exp.size());
AutoSeededRandomPool prng;
bool result = publicKey.Validate(prng,3);
if(result)
{
//载入公钥(ByteQueue,X509格式)
ECDSA< ECP,SHA256> ::验证者验证者(publicKey);

bool result = verifier.VerifyMessage(message.data(),messageIn.size(),signature.data(),signature.size());
if(result)
cout<< 消息上的验证签名<< ENDL;
else
cerr<< 无法验证消息上的签名<< ENDL;
}
else
{
cout<< 无法验证密钥<< ENDL;
}

这是切碎的,所以不会生成。任何帮助将是伟大的



PS我在这里问了一个类似的私人密钥问题

答案详见,但它并不明显。在给定曲线和公共点的情况下,您需要执行以下操作来初始化 publicKey

 串PT = 2DB45A3F21889438B42C8F464C75292BACF5FDDB5DA0B492501B299CBFE92D8F 
的DB90FC8FF4026129838B1BCAD1402CAE47FE7D8084E409A41AFCE16D63579C5F;

HexDecoder解码器;
decoder.Put((byte *)pt.data(),pt.size());
decoder.MessageEnd();

ECP ::点q;
size_t len = decoder.MaxRetrievable();
assert(len == SHA256 :: DIGESTSIZE * 2);

q.identity = false;
q.x.Decode(decoder,len / 2);
q.y.Decode(decoder,len / 2);

ECDSA< ECP,SHA256> :: PublicKey publicKey;
publicKey.Initialize(ASN1 :: secp256r1(),q);

bool result = publicKey.Validate(prng,3);
if(result)
{
cout<< 验证的公钥<< ENDL;
}
else
{
cerr<< 无法验证公钥<< ENDL;
exit(1);
}

const ECP :: Point& qq = publicKey.GetPublicElement();
cout<< Q.x:<< std :: hex<< qq.x<< ENDL;
cout<< Q.y:<< std :: hex<< qq.y<< ENDL;

以上程序产生以下结果:

< pre class =lang-none prettyprint-override> $ ./cryptopp-test.exe
已验证公钥
Qx:2db45a3f21889438b42c8f464c75292bacf5fddb5da0b492501b299cbfe92d8fh
Qy:db90fc8ff4026129838b1bcad1402cae47fe7d8084e409a41afce16d63579c5fh






测试:

  assert(len == SHA256 :: DIGESTSIZE * 2); 

是一种混合物。这是您想要使用的值,而不是 SHA256 :: DIGESTSIZE

  GetField()。MaxElementByteLength()

但是你不能使用它,因为唯一可用的东西是 x y 坐标。直到初始化底层 DL_GroupParameters_EC< ; EC>



举例来说,以下会导致分段错误:

  ECDSA< ECP,SHA256> :: PublicKey publicKey; 
unsigned int u = publicKey.GetGroupParameters()。GetCurve()。GetField()。MaxElementByteLength();
cout<< 字段元素长度:<< u < ENDL;






您可以篡改公钥以确保验证失败:

  qyDecode(decoder,len / 2); 
q.y ++;


I am struggling with the creation of a ECDSA public key from a string representation of a public key i.e

string     devicePublicKey("86FB5EB3CA0507226BE7197058B9EC041D3A3758D9D9C91902ACA3391F4E58AEF13AFF63CC4EF68942B9B94904DC1B890EDBEABD16B992110624968E894E560E");

previously I found that I had to prefix this key with '04' so not sure if this is require this time?

I am trying to generate it to use in verifying a signature

string ecs04b2ExpSignature("0199E984CEC75DDCA7F1DDF6E53E2E67352A2BE38A4B66F8ED596606FAB983FF300CAA76DE88CED9D563A5C03E8F3A7C000780F3F2061C611E9AA0B18B460D77");

where the data to be signed is

string      ecs04b2SigningData("020000000000000001FFFFFFFFFFFFFFFE123456789ABCDEF000B3DA2000000100000300000003030003000300");

My rough code for now looks like this

SecByteBlock message(convertHexStrToSecByteBlock(messageIn));
SecByteBlock signature(convertHexStrToSecByteBlock(signatureIn));

ECDSA<ECP, SHA256>::PublicKey publicKey;
string inPublicKey("04");
inPublicKey.append(pubKeyIn);
SecByteBlock pubKey = encryptBase::convertHexStrToSecByteBlock(inPublicKey);



ECP::Point p;
publicKey.AccessGroupParameters().Initialize(CryptoPP::ASN1::secp256r1());
publicKey.GetGroupParameters().GetCurve().DecodePoint(p, pubKey, publicKey.GetGroupParameters().GetCurve().EncodedPointSize(true));
publicKey.SetPublicElement(p);

//ByteQueue qt;
//qt.Put((byte*)exp.c_str(),(size_t)exp.size());
AutoSeededRandomPool prng;
bool result = publicKey.Validate(prng, 3);
if (result) 
{  
    // Load public key (in ByteQueue, X509 format)
    ECDSA<ECP, SHA256>::Verifier verifier(publicKey);

    bool result = verifier.VerifyMessage(message.data(), messageIn.size(), signature.data(), signature.size());
    if (result)
        cout << "Verified signature on message" << endl;
    else
        cerr << "Failed to verify signature on message" << endl;
}
else
{
    cout << "Failed to validate key" << endl;
}

this is chopped together so wont build. Any help would be great

PS I asked a similar question relating to private keys here Creation of ECDSA private key given curve and private exponent?

解决方案

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

string pt = "2DB45A3F21889438B42C8F464C75292BACF5FDDB5DA0B492501B299CBFE92D8F"
            "DB90FC8FF4026129838B1BCAD1402CAE47FE7D8084E409A41AFCE16D63579C5F";

HexDecoder decoder;
decoder.Put((byte*)pt.data(), pt.size());
decoder.MessageEnd();

ECP::Point q;
size_t len = decoder.MaxRetrievable();
assert(len == SHA256::DIGESTSIZE * 2);

q.identity = false;
q.x.Decode(decoder, len/2);
q.y.Decode(decoder, len/2);

ECDSA<ECP, SHA256>::PublicKey publicKey;
publicKey.Initialize(ASN1::secp256r1(), q);

bool result = publicKey.Validate( prng, 3 );
if( result )
{
    cout << "Validated public key" << endl;
}
else
{
    cerr << "Failed to validate public key" << endl;
    exit(1);
}

const ECP::Point& qq = publicKey.GetPublicElement();
cout << "Q.x: " << std::hex << qq.x << endl;
cout << "Q.y: " << std::hex << qq.y << endl;

The program above produces the following results.

$ ./cryptopp-test.exe
Validated public key
Q.x: 2db45a3f21889438b42c8f464c75292bacf5fddb5da0b492501b299cbfe92d8fh
Q.y: db90fc8ff4026129838b1bcad1402cae47fe7d8084e409a41afce16d63579c5fh


The test:

assert(len == SHA256::DIGESTSIZE * 2);

is kind of a kludge. This is the value you want to use instead of SHA256::DIGESTSIZE:

GetField().MaxElementByteLength()

But you can't use it because the only thing available are the x and y coordinates. Things like field size won't be available until you initialize the underlying DL_GroupParameters_EC< EC > in the public key.

As an example, the following causes a segmentation fault:

ECDSA<ECP, SHA256>::PublicKey publicKey;
unsigned int u = publicKey.GetGroupParameters().GetCurve().GetField().MaxElementByteLength();
cout << "Field element length: " << u << endl;


You can tamper with the public key to ensure a validation failure with:

q.y.Decode(decoder, len/2);
q.y++;

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

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