来源:http://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm
Elliptic Curve Digital Signature Algorithm, 或者 ECDSA, 是 FIPS-186. 定义的一种数字签名方法,当前版本是 Change 3, dated June 2009. 如果对非椭圆曲线变种有兴趣,看数字签名算法(Digital Signature Algorithm.)
当这些操作,比如说产生密匙,签名,验证可以进行,我们必须选择一个场和一个合适的域参数, 基于演示的目的,这个例子使用Fp 作为场. 这意味着一个这个模板参数必须包含ECP.如果我们使用 F2m, 那么模板参数就是 EC2N.
Crypto++ 提供了一些ANSI, Brainpool, and NIST提倡使用的曲线. Crypto++ 没有使用曲线产生功能,如果你需要使用自定义曲线,看 Elliptic Curve Builder.
测试代码
using namespace CryptoPP;
int Cecdsa_testDlg::test1(void)
{
AutoSeededRandomPool prng;
FileSource fs1( "private.ec.der", true /*pump all*/ );
FileSource fs2( "public.ec.der", true /*pump all*/ );
ECDSA<ECP, SHA256>::PrivateKey privateKey;
ECDSA<ECP, SHA256>::PublicKey publicKey;
// Load private key in PKCS #8 format
privateKey.Load( fs1 );
publicKey.Load(fs2);
bool result = privateKey.Validate( prng, 3 );
if( !result ) { return 1; }
ECDSA<ECP, SHA256>::Signer signer(privateKey);
std::string message = "Do or do not. There is no try.";
// signer.AccessKey().Initialize( prng, ASN1::secp160r1() );
// Determine maximum size, allocate a string with the maximum size
size_t siglen = signer.MaxSignatureLength();
std::string signature(siglen, 0x00);
// Sign, and trim signature to actual size
siglen = signer.SignMessage( prng, (const byte *)message.data(), message.size(), (byte *)signature.data() );
signature.resize(siglen);
ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
result = verifier.VerifyMessage( (const byte*)message.data(), message.size(), (const byte*)signature.data(), signature.size() );
if(result)
std::cout << "Verified signature on message" << std::endl;
else
std::cerr << "Failed to verify signature on message" << std::endl;
return 0;
}
int Cecdsa_testDlg::test2(void)
{
// Generating private/public pair
AutoSeededRandomPool rng;
//Generate a private key
ECDSA<ECP, CryptoPP::SHA256>::PrivateKey privateKey;
privateKey.Initialize(rng, CryptoPP::ASN1::secp256r1());
bool result = privateKey.Validate( rng, 3 );
if( !result ) { return 1; }
// Save private key in PKCS #8 format
FileSink fs1( "private.ec.der", true /*binary*/ );
privateKey.Save( fs1 );
// Generate publicKey
ECDSA<ECP, CryptoPP::SHA256>::PublicKey publicKey;
privateKey.MakePublicKey(publicKey);
// Save public key in X.509 format
FileSink fs2( "public.ec.der", true /*binary*/ );
publicKey.Save( fs2 );
// Serializing keys for later use
std::string tmp;
StringSink sink(tmp);
publicKey.Save(sink);
std::string out;
StringSource(tmp, true, new Base32Encoder(new StringSink(out)));
std::cout << out << std::endl; // <-- This prints full public key, same thing with private one
#if 0
// Loading private key and signing something
std::string privateKeyStr = "base32 encoded private key here";
ECIES<ECP>::PrivateKey privateKey;
ByteQueue bq;
StringSource(privateKeyStr, true, new Base32Decoder(new
Redirector(bq)));
privateKey.Load(bq);
AutoSeededRandomPool rng;
ECDSA<ECP>::Signer signer(privateKey);
std::string out;
std::string message = "message to sign, bla bla";
StringSource(message, true, new SignerFilter(rng, signer, new
Base32Encoder(new StringSink(out))));
std::cout << out << std::endl; // <-- this is base32 encoded signature for the message
// Loading public key and verifying signature
std::string publicKeyStr = "base32 encoded public key here";
ECIES<ECP>::PublicKey publicKey;
ByteQueue bq;
StringSource source(key, true, new Base32Decoder(new Redirector(bq)));
publicKey.Load(bq);
std::string message="message to sign, bla bla";
std::string signature32="base32 encoded signature";
std::string signature;
StringSource(signature32, true, new Base32Decoder(new
StringSink(signature)));
ECDSA<ECP>::Verifier verifier(publicKey);
if(verifier.VerifyMessage((const byte*)message.data(), message.size(),
(const byte*)signature.data(), signature.size()))
{
// Valid
}
#endif
return 0;
}