ecdsa 椭圆曲线数字签名算法

来源: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;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值