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?
Here's the answer to your second question on how to use
VerifyMessage
:Calling
Detach
on theHexDecoder
deletes the current filter, and replaces it with the new filter. In the code above, its theStringSink
. You have to do it to ensure memory is not leaked.Your message does not verify under the public key:
You can also try to verify the ASCII message rather than the binary message, but it fails to verify too:
So someone gave you the wrong message, the wrong signature or the wrong public key (or some combination).
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:The program above produces the following results.
You can't use
GetField().MaxElementByteLength()
because the only thing available are thex
andy
coordinates. Things like field size won't be available until you initialize the underlyingDL_GroupParameters_EC< EC >
in the public key.As an example, the following causes a segmentation fault:
You can tamper with the public key to ensure a validation failure with: