美文网首页
Crypto++安装与使用

Crypto++安装与使用

作者: Mr_Michael | 来源:发表于2023-02-05 10:08 被阅读0次

    一、简介

    Crypto++ 是一个免费开源的 C++ 密码学库,由 Wei Dai(美籍华裔)首次开发,当前由 Crypto++ 项目团队维护,源代码在 github 上进行托管。

    二、安裝 Crypto++ 庫

    1)套件安裝

    # ubutnu安裝 Crypto++ 函式庫
    sudo apt install libcrypto++-dev
    

    2)自行编译安装

    官网下载码源,或者从github clone。

    wget https://cryptopp.com/cryptopp870.zip
    unzip -a cryptopp870.zip -d cryptopp
    
    cd cryptopp
    #静态库编译【推荐】
    make -j4  # 或者 make static  -j4 
    #动态库编译
    make shared  -j4 
    
    # 測試 Crypto++ 函式庫
    ./cryptest.exe v
    
    # 安装
    sudo make install
    # 或
    make install PREFIX=./install_x86_64
    

    安装pem包到cryptopp

    • 以 PEM 格式读取和写入密钥和参数。
    git clone https://github.com/noloader/cryptopp-pem/* .git
    cp cryptopp-pem/*  cryptopp
    # 重新编译安装cryptopp
    

    交叉编译

    # 安装依赖,以aarch64为例
    sudo apt install binutils-aarch64-linux-gnu-dbg binutils-aarch64-linux-gnu cpp-aarch64-linux-gnu \
    g++-10-aarch64-linux-gnu g++-9-aarch64-linux-gnu g++-aarch64-linux-gnu g++ \
    gcc-10-aarch64-linux-gnu-base gcc-9-aarch64-linux-gnu-base gcc-aarch64-linux-gnu \
    pkg-config-aarch64-linux-gnu qemu-efi-aarch64 gcc arch-test
    
    # 需指定编译器
    make CXX=aarch64-linux-gnu-g++ CXXFLAGS="-O2 -fPIC -pipe -Wall -shared" -f GNUmakefile-cross  -j4
    

    三、程序开发

    c++ 使用Crypto++开发文章

    1.示例1

    ECB 模式、16字节长度的 key、PKCS7填充方式的场景下,使用 AES 算法进行加解密。

    #include <iostream>
    #include <string>
    #include "cryptlib.h"
    #include "aes.h"
    #include "modes.h"
    #include "files.h"
    #include "osrng.h"
    #include "hex.h"
    
    using namespace CryptoPP;
    using namespace std;
    
    int main(int argc, char* argv[]) {
        // 建立隨機亂數產生器
        // AutoSeededRandomPool prng;
        // 將金鑰與 IV 放置於安全的記憶體空間
        // SecByteBlock key(AES::DEFAULT_KEYLENGTH); // 採用預設的金鑰長度(128 位元)
        // SecByteBlock key(AES::MAX_KEYLENGTH);  // 採用最長的金鑰長度(256 位元)
        // SecByteBlock key(24);                  // 自行指定金鑰長度(192 位元)
        // 產生隨機金鑰與 IV
        // prng.GenerateBlock(key, key.size());
        
        byte key[AES::DEFAULT_KEYLENGTH] = "abcd1234";
    
        // 原始資料
        std::string plain = "Crypto++ is a free C++ library for cryptography";
    
        // 用來儲存密文與明文的變數
        std::string cipher, encoded, recovered;
    
        std::cout << "key:" << key << std::endl;
        std::cout << "原始資料:" << plain << std::endl;
    
        try {
            // 採用 AES-ECB 加密
            ECB_Mode<AES>::Encryption e;
    
            // 設定金鑰
            e.SetKey(key, sizeof(key));
    
            // 進行加密
            StringSource s(plain, true,
                new StreamTransformationFilter(e,
                    new StringSink(cipher)
                ) // StreamTransformationFilter
            ); // StringSource
    
        } catch(const Exception& e) {
            std::cerr << e.what() << std::endl;
            return EXIT_FAILURE;
        }
    
        // Pretty print cipher text
        StringSource ss2( cipher, true,
            new HexEncoder(
                new StringSink( encoded )
            ) // HexEncoder
        ); // StringSource
        std::cout << "cipher text: " << encoded << std::endl;
    
        try {
            // 採用 AES-ECB 解密
            ECB_Mode<AES>::Decryption d;
    
            // 設定金鑰與 IV
            d.SetKey(key, sizeof(key));
    
            // 進行解密
            StringSource s(cipher, true,
                new StreamTransformationFilter(d,
                    new StringSink(recovered)
                ) // StreamTransformationFilter
            ); // StringSource
    
        } catch(const Exception& e) {
            std::cerr << e.what() << std::endl;
            return EXIT_FAILURE;
        }
    
        std::cout << "解開的明文:" << recovered << std::endl;
    
        return EXIT_SUCCESS;
    }
    

    2.示例2

    通过RSA对数据进行签署和验签。

    #include <string>
    #include <iostream>
    #include <cstdlib>
    #include "rsa.h"
    #include "pssr.h"
    #include "sha.h"
    #include "osrng.h"
    #include "secblock.h"
    
    #include "files.h"
    #include "hex.h"
    #include <pem.h>
    
    using namespace CryptoPP;
    using namespace std;
    
    void SaveKey( const RSA::PublicKey& PublicKey, const string& filename, const string format)
    {
        if (format == "pem") {
            FileSink file( filename.c_str(), true /*binary*/ );
            CryptoPP::PEM_Save(file, PublicKey);
        } else if (format == "binary") {
            // DER Encode Key - X.509 key format
            PublicKey.Save(
                FileSink( filename.c_str(), true /*binary*/ ).Ref()
            );
        }
    }
    
    void SaveKey( const RSA::PrivateKey& PrivateKey, const string& filename, const string format)
    {
        if (format == "pem") {
            FileSink file( filename.c_str(), true /*binary*/ );
            CryptoPP::PEM_Save(file, PrivateKey);
        } else if (format == "binary") {
            // DER Encode Key - PKCS #8 key format
            PrivateKey.Save(
                FileSink( filename.c_str(), true /*binary*/ ).Ref()
            );
        }
    }
    
    void LoadKey( const string& filename, RSA::PublicKey& PublicKey, const string format)
    {
        if (format == "pem") {
            FileSource file(filename.c_str(), true, NULL, true /*binary*/ );
            PEM_Load(file, PublicKey);
        } else  if (format == "binary") {
            // DER Encode Key - X.509 key format
            PublicKey.Load(
                FileSource(filename.c_str(), true, NULL, true /*binary*/ ).Ref()
            );
        }
    }
    
    void LoadKey( const string& filename, RSA::PrivateKey& PrivateKey, const string format)
    {
        if (format == "pem") {
            FileSource file(filename.c_str(), true, NULL, true /*binary*/ );
            PEM_Load(file, PrivateKey);
        } else  if (format == "binary") {
            // DER Encode Key - PKCS #8 key format
            PrivateKey.Load(
                FileSource(filename.c_str(), true, NULL, true /*binary*/ ).Ref()
            );
        }
    }
    
    int main(int argc, char* argv[]) {
    
        // 建立隨機亂數產生器
        AutoSeededRandomPool prng;
    
        try {
            // 產生 RSA 私鑰
            RSA::PrivateKey rsaPrivKey;
            rsaPrivKey.GenerateRandomWithKeySize(prng, 1024);
            // 產生對應的 RSA 公鑰
            RSA::PublicKey rsaPubKey(rsaPrivKey);
            SaveKey(rsaPrivKey, "rsaPrivKey.pem", "pem");
            SaveKey(rsaPubKey, "rsaPubkey.pem", "binary");
    
            // RSA::PrivateKey rsaPrivKey;
            // RSA::PublicKey rsaPubKey;
            // LoadKey("rsaPrivKey.pem", rsaPrivKey);
            // LoadKey("rsaPubkey.pem", rsaPubKey);
    
            // 資料內容
            std::string message = "Yoda said, Do or Do Not. There is not try.";
    
            // 數位簽章
            std::string signature;
    
            // 簽署器
            RSASS<PSS, SHA256>::Signer signer(rsaPrivKey);
    
            // 對資料進行簽署
            StringSource(message, true,
                new SignerFilter(prng, signer,
                    new StringSink(signature)
                ) // SignerFilter
            ); // StringSource
    
            std::string encoded;
            StringSource ss2( signature, true,
                new HexEncoder(
                    new StringSink( encoded )
                ) // HexEncoder
            ); // StringSource
            std::cout << "簽署: " << encoded << std::endl;
    
            // 簽章驗證器
            RSASS<PSS, SHA256>::Verifier verifier(rsaPubKey);
    
            // 驗證數位簽章
            StringSource(message+signature, true,
                new SignatureVerificationFilter(
                    verifier, NULL,
                    SignatureVerificationFilter::THROW_EXCEPTION
                    | SignatureVerificationFilter::SIGNATURE_AT_END
                ) // SignatureVerificationFilter
            ); // StringSource
    
            std::cout << "簽章驗證成功" << std::endl;
    
        } catch(CryptoPP::Exception& e) {
            std::cerr << e.what() << std::endl;
        }
        return EXIT_SUCCESS;
    }
    

    参考

    相关文章

      网友评论

          本文标题:Crypto++安装与使用

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