美文网首页
基于Crypto++密码库的ECIES和ECDSA算法的联合使用

基于Crypto++密码库的ECIES和ECDSA算法的联合使用

作者: right_33cb | 来源:发表于2018-10-15 16:45 被阅读0次

    转:https://blog.csdn.net/GuoXuan_CHN/article/details/80532258

    基于Crypto++密码库的ECIES和ECDSA算法的联合使用

    转载请注明出处

    Auteur:GX

    CSDN:GuoXuan_CHN

    使用背景

    毕设要求使用ECC椭圆曲线加密算法为用户信息加密,并数字签名。鉴于设计要求,ECIES的公私钥同样为ECDSA的公私钥。数字签名是后加部分。在已完成的设计部分中,ECIES的公私钥已将转化为std::string类型,在最小改动前提下,做出程序。

    软件平台

    Crypto++ - 7.0.0

    MacBook pro - 10.13.4

    GCC - Configured with: –prefix=/Applications/Xcode.app/Contents/Developer/usr –with-gxx-include-dir=/usr/include/c++/4.2.1;Apple LLVM version 9.1.0 (clang-902.0.39.1)

    设计语言 - C++

    用前必读

    在中文程序员网站上,有关Crypto++的ECDSA的使用Demo很少。我是查看Crypto++官网上的维基百科中的使用介绍来写出的。本文章并非旨在教学,而是旨在记录,其中我所提供的Demo根据我自身需求有所更改。如果本文章不能帮助你,请查看Crypto++官网中您所需求的函数的使用方法。本文的使用方法是我偶然发现,并尝试出可用,但我并不知道原理,如果您放在您的程序中,出现任何问题,我不负任何责任

    发现过程

    ECC公钥(第一组) - 3059301306072A8648CE3D020106082A8648CE3D0301070342000432AAB20C1C02D8844834D5AAC7E12814A53266AA5F0350190A9C1A9C43AA4178FFDC04D0785EE52676D061B5D836FEB34D766E710CE2196B5ADAF7876E805C01

    ECC私钥(第一组)- 3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420C044B0620BAC02DA779426C1292A6398AA7EB99D9F624E9921186211AFFB6117

    ECC公钥(第二组)- 3059301306072A8648CE3D020106082A8648CE3D030107034200045EF50890EDC7FAAA2420533FA500AC897236DDE114A4FE7215B48F908585208E3DD9F1CEB1D923EEDB3C95027D82FE6AF64F82CB61631DEB7B68028899D7328C

    ECC私钥(第二组)- 3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420FD9BB947E95A503645CAD68DC70E21E3D04AF2C52206B9057ED52D94299E93BE

    ECC公钥(第三组)- 3059301306072A8648CE3D020106082A8648CE3D0301070342000419514747D4D4F91C484DC529D1695E05D8383D04EB6D84A0BF40C4641CB3490FF17BF5ECA97A7C0F325D62C5EE2180D9C5ABC977CBEE1A40B45F5B32EB1F61F3

    ECC私钥(第三组)- 3041020100301306072A8648CE3D020106082A8648CE3D0301070427302502010104203DB7FB2335C3368485C1A51AD9F36FA3FF4B2BC187D0D3FAE40977066EE74116

    是的,你可能发现了。ECC公钥的前54个字符是相通的,每次变化的只是后面的。同理,ECC私钥每次变化的也只是前70个字符,我猜想,是不是后面变化的才是公私钥。经过尝试,可以使用充当ECDSA的公私钥。

    ECIES加解密Demo

    该Demo是我从网上找到的,网上有很多Demo,但是有些我发现用不了,在可用的Demo中最符合我需求的是这个,同时,我稍微进行了更改。如有侵权,告知必删。

    #include <iostream>

    #include "eccrypto.h"

    #include "osrng.h"

    #include "oids.h"

    #include "hex.h"

    #include "filters.h"

    #ifndef ECC_ENCRYPTION_ALGORITHM_H_

    #define ECC_ENCRYPTION_ALGORITHM_H_

    #include<string>

    class EccEncryption

    {

    public:

        /// This method is used to generate keys for ECC encryption algorithm

        ///

        ///  \param[in]  uiKeySize, length of key

        /// \param[out]  sPrivateKey, private key

        /// \param[out]  sPublicKey, public key

        void GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey);

        /// This method is used to encrypt the input message using public key

        ///

        ///  \param[in]  sPublicKey, public key generated by the first method

        /// \param[out]  sMsgToEncrypt, message to encryppt

        /// \return  the message encrypted using the input public key

        std::string Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt);

        /// This method is used to decrypt the input message using private key

        ///

        /// \param[in] sPrivateKey, private key used to decrypt the cipher text

        /// \param[in] sMsgToDecrypt, cipher text used to decrypt to get the plain text

        /// \return decrypted plain text

        std::string Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp);

    };

    #endif

    void EccEncryption::GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey)

    {

        using namespace CryptoPP;

        // Random pool, the second parameter is the length of key

        // 随机数池,第二个参数是生成密钥的长

        AutoSeededRandomPool rnd(false, 256);

        ECIES<ECP>::PrivateKey  privateKey;

        ECIES<ECP>::PublicKey  publicKey;

        // Generate private key

        privateKey.Initialize(rnd, ASN1::secp256r1());

        // Generate public key using private key

        privateKey.MakePublicKey(publicKey);

        ECIES<ECP>::Encryptor encryptor(publicKey);

        HexEncoder pubEncoder(new StringSink(sPublicKey));

        publicKey.DEREncode(pubEncoder);

        pubEncoder.MessageEnd();

        ECIES<ECP>::Decryptor decryptor(privateKey);

        HexEncoder prvEncoder(new StringSink(sPrivateKey));

        privateKey.DEREncode(prvEncoder);

        prvEncoder.MessageEnd();

    }

    std::string EccEncryption::Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt)

    {

        using namespace CryptoPP;

        // If to save the keys into a file, FileSource should be replace StringSource

        StringSource pubString(sPublicKey, true, new HexDecoder);

        ECIES<ECP>::Encryptor encryptor(pubString);

        // Calculate the length of cipher text

        size_t uiCipherTextSize = encryptor.CiphertextLength(sMsgToEncrypt.size());

        std::string sCipherText;

        sCipherText.resize(uiCipherTextSize);

        RandomPool rnd;

        encryptor.Encrypt(rnd, (byte*)(sMsgToEncrypt.c_str()), sMsgToEncrypt.size(), (byte*)(sCipherText.data()));

        return sCipherText;

    }

    std::string EccEncryption::Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp)

    {

        using namespace CryptoPP;

        StringSource privString(sPrivateKey, true, new HexDecoder);

        ECIES<ECP>::Decryptor decryptor(privString);

        auto sPlainTextLen = decryptor.MaxPlaintextLength(sMsgToDecrytp.size());

        std::string sDecryText;

        sDecryText.resize(sPlainTextLen);

        RandomPool rnd;

        decryptor.Decrypt(rnd, (byte*)sMsgToDecrytp.c_str(), sMsgToDecrytp.size(), (byte*)sDecryText.data());

        return sDecryText;

    }

    int main()

    {

        std::string sStrToTest = std::string("Hello world. This is an example of Ecc encryption algorithm of Crypto++ open source library.");

        EccEncryption ecc;

        std::string sPrivateKey, sPublicKey;

        ecc.GenerateEccKeys(1024, sPrivateKey, sPublicKey);

        std::cout << "Generated private key is : "<< std::endl;

        std::cout << sPrivateKey << std::endl;

        std::cout << "***********************************************************" << std::endl;

        std::cout << "Generated public key is : "<< std::endl;

        std::cout << sPublicKey << std::endl;

        std::cout << "***********************************************************" << std::endl;

        std::cout << "The message to be encrypted is : " << std::endl;

        std::cout << sStrToTest << std::endl;

        std::cout << "***********************************************************" << std::endl;

        std::string sEncryptResult = ecc.Encrypt(sPublicKey, sStrToTest);

        std::cout << "The result of encrypt is : " << std::endl;

        std::cout << sEncryptResult << std::endl;

        std::cout << "***********************************************************" << std::endl;

        std::string sDecryptResult = ecc.Decrypt(sPrivateKey, sEncryptResult);

        std::cout << "The result of decrypt is : " << std::endl;

        std::cout << sDecryptResult << std::endl;

        std::cout << "***********************************************************" << std::endl;

        return 0;

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    ECIES-ECSDSA联合使用Demo

    /*

    auteur:GX

    CSDN:GuoXuan_CHN

    */

    #include <fstream>

    #include <string>

    #include <iostream>

    #include "eccrypto.h"

    #include "osrng.h"

    #include "oids.h"

    #include "hex.h"

    #include "filters.h"

    #include "des.h"

    using namespace std;

    CryptoPP::ECIES<CryptoPP::ECP>::PrivateKey  ePrivateKey;

    CryptoPP::ECIES<CryptoPP::ECP>::PublicKey  ePublicKey;

    string sPrivateKey, sPublicKey;

    void GenerateEccKeys()

    {

        using namespace CryptoPP;

        // Random pool, the second parameter is the length of key

        // 随机数池,第二个参数是生成密钥的长

        AutoSeededRandomPool rnd(false, 256);

        // Generate private key

        // 生成私钥

        ePrivateKey.Initialize(rnd, ASN1::secp256r1());

        // Generate public key using private key

        // 用私钥生成密钥

        ePrivateKey.MakePublicKey(ePublicKey);

        HexEncoder pubEncoder(new StringSink(sPublicKey));

        ePublicKey.DEREncode(pubEncoder);

        pubEncoder.MessageEnd();

        HexEncoder prvEncoder(new StringSink(sPrivateKey));

        ePrivateKey.DEREncode(prvEncoder);

        prvEncoder.MessageEnd();

    }

    string signe (string message)

    {

        std::string signature="";

        //数字签名过程

        CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PrivateKey privateKey;

        std::string exp = sPrivateKey.substr(70);

        CryptoPP::HexDecoder decoder;

        decoder.Put((CryptoPP::byte *)&exp[0], exp.size());

        decoder.MessageEnd();

        CryptoPP::Integer x;

        x.Decode(decoder, decoder.MaxRetrievable());

        privateKey.Initialize(CryptoPP::ASN1::secp256r1(), x);

        CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::Signer signer( privateKey );

        CryptoPP::AutoSeededRandomPool prng;

        //签名结果

        signature = "";

        CryptoPP::StringSource s( message, true /*pump all*/,

                                new  CryptoPP::SignerFilter( prng,

                                                            signer,

                                                            new  CryptoPP::StringSink( signature )

                                                            ) // SignerFilter

                                ); // StringSource

        return signature;

        //签名过程结束

    }

    bool VerifierSignature(string signature,string message)

    {

        std::string pt="";

        //验签过程

        CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PublicKey publicKey;

        pt = sPublicKey.substr(54);

        CryptoPP::HexDecoder decoder;

        decoder.Put((CryptoPP::byte *)&pt[0], pt.size());

        decoder.MessageEnd();

        CryptoPP::ECP::Point q;

        size_t len = decoder.MaxRetrievable();

        q.identity = false;

        q.x.Decode(decoder, len/2);

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

        publicKey.Initialize( CryptoPP::ASN1::secp256r1(), q );

        CryptoPP::ECDSA<CryptoPP::ECP,CryptoPP::SHA1>::Verifier verifier(publicKey);

        // Result of the verification process

        bool result = false;

        CryptoPP::StringSource ss( signature+message, true /*pump all*/,

                                  new CryptoPP::SignatureVerificationFilter(

                                                                            verifier,

                                                                            new CryptoPP::ArraySink((CryptoPP::byte *)&result, sizeof(result) )

                                                                            )

                                  );

        return result;

    }

    int main()

    {

        std::string message = "Yoda said, Do or do not. There is no try.";

        std::string signature="";

        bool result = false;

        GenerateEccKeys();

        signature = signe (message);

        result = VerifierSignature(signature,message);

        cout << "****** tester la bon*****" << endl;

        cout << result << endl;

        result = VerifierSignature(signature,"1234567890");

        cout << "****** tester la mauvais*****" << endl;

        cout << result << endl;

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    编译指令

    该指令为在我本机上使用的指令,请合理更改

    g++ Demo_ECDSA.cpp  -g -o prog -I /usr/local/include/cryptopp -lcryptopp

    ---------------------

    作者:GuoXuan_CHN

    来源:CSDN

    原文:https://blog.csdn.net/GuoXuan_CHN/article/details/80532258?utm_source=copy

    版权声明:本文为博主原创文章,转载请附上博文链接!

    相关文章

      网友评论

          本文标题:基于Crypto++密码库的ECIES和ECDSA算法的联合使用

          本文链接:https://www.haomeiwen.com/subject/vqafzftx.html