cryptopp 加密库使用

2020-08-11

cryptopp 是 c++ 加解密库,包含了大部分主流的加解密实现功能。详细可以查看官方文档。本章主要是写 demo,测试 cryptopp 的使用。


1. 安装

1.1. 命令安装

  • MacOS
1
brew install cryptopp
  • Linux
1
yum install cryptopp

1.2. 源码安装

1
2
3
4
5
6
7
8
9
wget https://codeload.github.com/weidai11/cryptopp/tar.gz/refs/tags/CRYPTOPP_8_5_0
tar zxf cryptopp-CRYPTOPP_8_5_0.tar.gz
cd cryptopp-CRYPTOPP_8_5_0
# 编译静态库
make
# 编译动态库
make libcryptopp.so
# 安装
sudo make install

2. 算法使用

github 测试代码

2.1. gzip

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
bool gzip(const std::string& src, std::string& dst) {
    try {
        CryptoPP::Gzip zip;
        zip.Put((byte*)src.c_str(), src.size());
        zip.MessageEnd();

        CryptoPP::word64 avail = zip.MaxRetrievable();
        if (avail) {
            dst.resize(avail);
            zip.Get((byte*)&dst[0], dst.size());
        }
    } catch (CryptoPP::InvalidDataFormat& e) {
        std::cout << e.GetWhat() << std::endl;
        return false;
    }
    return true;
}

bool ungzip(const std::string& src, std::string& dst) {
    try {
        CryptoPP::Gunzip zip;
        zip.Put((byte*)src.c_str(), src.size());
        zip.MessageEnd();
        CryptoPP::word64 avail = zip.MaxRetrievable();
        if (avail) {
            dst.resize(avail);
            zip.Get((byte*)&dst[0], dst.size());
        }
    } catch (CryptoPP::InvalidDataFormat& e) {
        std::cout << e.GetWhat() << std::endl;
        return false;
    }
    return (true);
}

void test_gzip() {
    std::cout << "test gzip:" << std::endl;
    // gzip
    std::string src("hello world!"), dst;
    if (gzip(src, dst)) {
        std::cout << "gzip: " << dst << std::endl;
    } else {
        std::cout << "gzip failed!" << std::endl;
    }

    // ungizp
    if (ungzip(dst, src)) {
        std::cout << "ungzip: " << src << std::endl;
    } else {
        std::cout << "ungzip failed!" << std::endl;
    }
}

2.2. aes crt

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
std::string aes_crt_encrypt(const std::string& k1, const std::string& iv1, const std::string& message) {
    using namespace CryptoPP;

    std::string encrypted;

    CryptoPP::SecByteBlock key(16), iv(16);
    std::memcpy(key, k1.c_str(), k1.size());
    std::memcpy(iv, iv1.c_str(), iv1.size());

    std::cout << "k1: " << k1 << " len: " << iv1.length() << std::endl
              << "iv1: " << iv1 << " len: " << iv1.length() << std::endl;

    AES::Encryption aesEncryption(key, key.size());
    CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv);

    StreamTransformationFilter stfEncryptor(
        ctrEncryption, new StringSink(encrypted));

    stfEncryptor.Put((const byte*)&message[0], message.size());
    stfEncryptor.MessageEnd();
    return encrypted;
}

std::string aes_crt_decrypt(const std::string& k1, const std::string& iv1, std::string encrypted) {
    using namespace CryptoPP;

    std::string decrypted;

    CryptoPP::SecByteBlock key(16), iv(16);
    std::memcpy(key, k1.c_str(), k1.size());
    std::memcpy(iv, iv1.c_str(), iv1.size());

    std::cout << "encrypted data cnt: " << encrypted.length() << std::endl
              << "-----" << std::endl;

    AES::Encryption aesDecryption(key, key.size());
    CTR_Mode_ExternalCipher::Decryption ctrDecryption(aesDecryption, iv);

    StreamTransformationFilter stfDecryptor(
        ctrDecryption, new StringSink(decrypted));

    std::cout << "encrypted size: " << encrypted.size() << std::endl;

    stfDecryptor.Put((const byte*)&encrypted[0], encrypted.size());
    stfDecryptor.MessageEnd();

    std::cout << "recovered data len: " << decrypted.length() << std::endl;
    return decrypted;
}

void test_aes_crt() {
    std::string encrypted, decrypted, message;
    std::string key = "1234567890123456";
    std::string iv = "1234567890123456";
    message =
        "Now is the time for all good men "
        "to come to the aide of their country.";
    encrypted = aes_crt_encrypt(key, iv, message);
    decrypted = aes_crt_decrypt(key, iv, encrypted);
    std::cout << "decrypt data: " << decrypted << std::endl;
}

2.3. md5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::string md5(const std::string& text) {
    /* https://www.cryptopp.com/wiki/MD5 */
    std::string digest;
    CryptoPP::Weak1::MD5 md5;
    CryptoPP::HashFilter hashfilter(md5);
    hashfilter.Attach(new CryptoPP::HexEncoder(new CryptoPP::StringSink(digest), false));
    hashfilter.Put(reinterpret_cast<const unsigned char*>(text.c_str()), text.length());
    hashfilter.MessageEnd();
    return digest;
}

void test_md5() {
    std::cout << "test md5:" << std::endl;
    std::cout << md5("hello world!").c_str() << std::endl;
}

3. 参考