crypto++
2017-12-28 17:48 woodzcl 阅读(442) 评论(0) 编辑 收藏 举报CryptoPP库是一个C++书写的加密算法库,很棒。
在如今的抛却数字证书体系下,只关注公私钥对的情况下,我认为存粹的加解密算法库很有市场,虽然我以前觉得PolarSSL的加解密算法实现不错,但不影响我对CryptoPP的热情
今天,介绍一下,CryptoPP的椭圆曲线加/解密和签名/延签问题,当然是提供源码来说话了
——————————————————————————————————————————
//ecc-enc-dec.h
#ifndef ECC_ENC_DEC_H
#define ECC_ENC_DEC_H
#include <string>
void genEccEncKeys(unsigned int uiKeySize, std::string &priKey, std::string &pubKey);
void genEccSignKeys(unsigned int uiKeySize, std::string &priKey, std::string &pubKey);
std::string ecc_pri_signature(const std::string priKey, const std::string msgToSign);
std::string ecc_pub_encrypt(const std::string pubKey, const std::string msgToEncrypt);
std::string ecc_pri_decrypt(const std::string priKey, const std::string msgToDecrypt);
int ecc_pub_verify(const std::string pubKey, const std::string msgToSign, const std::string msgSigned);
#endif
//ecc-enc-dec.c
#include "ecc-enc-dec.h"
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include "hex.h"
#include "filters.h"
using namespace CryptoPP;
void genEccEncKeys(unsigned int uiKeySize, std::string &priKey, std::string &pubKey)
{
AutoSeededRandomPool rnd(false, uiKeySize);
ECIES<ECP>::PrivateKey privateKey;
ECIES<ECP>::PublicKey publicKey;
privateKey.Initialize(rnd, ASN1::secp521r1());
privateKey.MakePublicKey(publicKey);
ECIES<ECP>::Encryptor encryptor(publicKey);
HexEncoder pubEncoder(new StringSink(pubKey));
encryptor.DEREncode(pubEncoder);
pubEncoder.MessageEnd();
ECIES<ECP>::Decryptor decryptor(privateKey);
HexEncoder priEncoder(new StringSink(priKey));
decryptor.DEREncode(priEncoder);
priEncoder.MessageEnd();
}
void genEccSignKeys(unsigned int uiKeySize, std::string &priKey, std::string &pubKey)
{
AutoSeededRandomPool rnd(false, uiKeySize);
ECDSA<ECP, SHA256>::PrivateKey privateKey;
ECDSA<ECP, SHA256>::PublicKey publicKey;
privateKey.Initialize(rnd, ASN1::secp521r1());
privateKey.MakePublicKey(publicKey);
StringSink priSs(priKey);
privateKey.Save(priSs);
StringSink pubSs(pubKey);
publicKey.Save(pubSs);
}
std::string ecc_pri_signature(const std::string priKey, const std::string msgToSign)
{
std::string signedText;
ECDSA<ECP, SHA256>::PrivateKey privateKey;
StringSource Ss(priKey, true);
privateKey.Load(Ss);
ECDSA<ECP, SHA256>::Signer signer(privateKey);
size_t siglen = signer.MaxSignatureLength();
signedText.resize(siglen);
RandomPool rnd;
siglen = signer.SignMessage(rnd, (byte*)msgToSign.data(), msgToSign.size(), (byte*)signedText.data());
signedText.resize(siglen);
return signedText;
}
std::string ecc_pub_encrypt(const std::string pubKey, const std::string msgToEncrypt)
{
std::string cipherText;
// if to save the key into a file, FileSource should be replace StringSource
StringSource pubString(pubKey, true, new HexDecoder);
ECIES<ECP>::Encryptor encryptor(pubString);
size_t uiCipherTextSize = encryptor.CiphertextLength(msgToEncrypt.size());
cipherText.resize(uiCipherTextSize);
RandomPool rnd;
encryptor.Encrypt(rnd, (byte*)msgToEncrypt.c_str(), msgToEncrypt.size(), (byte*)cipherText.data());
return cipherText;
}
std::string ecc_pri_decrypt(const std::string priKey, const std::string msgToDecrypt)
{
std::string decryptText;
StringSource priString(priKey, true, new HexDecoder);
ECIES<ECP>::Decryptor decryptor(priString);
size_t uiDecryptTextSize = decryptor.MaxPlaintextLength(msgToDecrypt.size());
decryptText.resize(uiDecryptTextSize);
RandomPool rnd;
decryptor.Decrypt(rnd, (byte*)msgToDecrypt.c_str(), msgToDecrypt.size(), (byte*)decryptText.data());
return decryptText;
}
int ecc_pub_verify(const std::string pubKey, const std::string msgToSign, const std::string msgSigned)
{
ECDSA<ECP, SHA256>::PublicKey publicKey;
StringSource Ss(pubKey, true);
publicKey.Load(Ss);
RandomPool rnd;
publicKey.Validate(rnd, 3);
ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
bool result = verifier.VerifyMessage((byte*)msgToSign.data(), msgToSign.size(), (byte*)msgSigned.data(), msgSigned.size());
if (result)
{
return 1;
}
else
{
return 0;
}
}
//ecc-test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "ecc-enc-dec.h"
int main()
{
std::string srcText = std::string("Hello world.");
std::string enc_priKey, enc_pubKey;
genEccEncKeys(1024, enc_priKey, enc_pubKey);
std::string encryptResult = ecc_pub_encrypt(enc_pubKey, srcText);
printf("public key enc result: %s--\nlength: %d\n", encryptResult.c_str(), (int)encryptResult.size());
std::string decryptResult = ecc_pri_decrypt(enc_priKey, encryptResult);
printf("private key dec result: %s--\nlength: %d\n", decryptResult.c_str(), (int)decryptResult.size());
std::string sign_priKey, sign_pubKey;
genEccSignKeys(1024, sign_priKey, sign_pubKey);
std::string signedResult = ecc_pri_signature(sign_priKey, srcText);
printf("private key sign result: %s--\nlength: %d\n", signedResult.c_str(), (int)signedResult.size());
int bVerify = ecc_pub_verify(sign_pubKey, srcText, signedResult);
printf("public key verify result: %d\n", 0==bVerify?false:true);
return 0;
}
//result
# ./ecc-test
public key enc result: (YR¨º͂j(&Y펠⥣`풶±ȍ줊\aR;ĬX8ܒ0,(ÿ,5--
length: 165
private key dec result: Hello world.--
length: 12
private key sign result: ¶µZH!ܻpn_ᯕ0R¤H--
length: 132
public key verify result: 1
Finally:
这里是非对称ECC算法,数学理论部分我就没打算搞懂!!
CryptoPP的问题是编译出来的应用至少都在15M左右,也就是太大了。