Conan客户端简单使用示例
? ? ? 在https://blog.csdn.net/fengbingchun/article/details/118443862 中對Conan進(jìn)行了簡單介紹,這里調(diào)用openssl的接口,寫一個(gè)簡單的test來說明Conan的使用步驟:
? ? ? (1).首先添加一個(gè)conanfile.txt文件,內(nèi)容如下:依賴項(xiàng)為openssl最新版1.1.1k
[requires]
openssl/1.1.1k[generators]
cmake
? ? ? (2).依次執(zhí)行如下命令:
mkdir build
cd build
~/Disk/anaconda3/envs/test_conan/bin/conan install .. -s arch=x86_64 -s compiler=gcc -s compiler.libcxx=libstdc++ -s compiler.version=4.9 -s os=Linux --build=missing
? 執(zhí)行結(jié)果如下圖所示:openssl生成的庫和頭文件會(huì)存放在~/.conan/data/openssl/1.1.1k/_/_/package/93fdb97b4b95d2b3f87d615ef63cbbfa72870a99目錄下。
? ? 在當(dāng)前build目錄下還會(huì)生成conanbuildinfo.cmake、conanbuildinfo.txt、conaninfo.txt、 conan.lock、graph_info.json 5個(gè)文件:
? ? ? conanbuildinfo.cmake:定義了一些宏和變量,指定openssl庫和頭文件的所在路徑等信息,此文件需要在主CMakeLists.txt中被include。
? ? ? conanbuildinfo.txt:指定openssl庫、頭文件、可執(zhí)行文件所在路徑等信息。
? ? ? conaninfo.txt:指定編譯openssl時(shí)的配置信息,及哪些openssl選項(xiàng)是開啟的。
? ? ? conan.lock:與connaninfo.txt內(nèi)容類似。
? ? ? graph_info.json:與connaninfo.txt內(nèi)容類似,指示哪些openssl選項(xiàng)是開啟的。
? ? ? (3).main.cpp文件內(nèi)容如下:參考https://blog.csdn.net/fengbingchun/article/details/106113185 ,使用對稱加密算法AES對字符串進(jìn)行加解密
#include <string.h>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
#include <openssl/des.h>
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/aes.h>
#include <openssl/hmac.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>namespace {static const unsigned char gcm_key[] = { // 32 bytes, Key0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
};static const unsigned char gcm_iv[] = { // 12 bytes, IV(Initialisation Vector)0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};// Additional Authenticated Data(AAD): it is not encrypted, and is typically passed to the recipient in plaintext along with the ciphertext
static const unsigned char gcm_aad[] = { // 16 bytes0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43,0x7f, 0xec, 0x78, 0xde
};std::unique_ptr<unsigned char[]> aes_gcm_encrypt(const char* plaintext, int& length, unsigned char* tag)
{EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();// Set cipher type and modeEVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);// Set IV length if default 96 bits is not appropriateEVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), nullptr);// Initialise key and IVEVP_EncryptInit_ex(ctx, nullptr, nullptr, gcm_key, gcm_iv);// Zero or more calls to specify any AADint outlen;EVP_EncryptUpdate(ctx, nullptr, &outlen, gcm_aad, sizeof(gcm_aad));unsigned char outbuf[1024];// Encrypt plaintextEVP_EncryptUpdate(ctx, outbuf, &outlen, (const unsigned char*)plaintext, strlen(plaintext));length = outlen;std::unique_ptr<unsigned char[]> ciphertext(new unsigned char[length]);memcpy(ciphertext.get(), outbuf, length);// Finalise: note get no output for GCMEVP_EncryptFinal_ex(ctx, outbuf, &outlen);// Get tagEVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf);memcpy(tag, outbuf, 16);// Clean upEVP_CIPHER_CTX_free(ctx);return ciphertext;
}std::unique_ptr<unsigned char[]> aes_gcm_decrypt(const unsigned char* ciphertext, int& length, const unsigned char* tag)
{EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();// Select cipherEVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);// Set IV length, omit for 96 bitsEVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), nullptr);// Specify key and IVEVP_DecryptInit_ex(ctx, nullptr, nullptr, gcm_key, gcm_iv);int outlen;// Zero or more calls to specify any AADEVP_DecryptUpdate(ctx, nullptr, &outlen, gcm_aad, sizeof(gcm_aad));unsigned char outbuf[1024];// Decrypt plaintextEVP_DecryptUpdate(ctx, outbuf, &outlen, ciphertext, length);// Output decrypted blocklength = outlen;std::unique_ptr<unsigned char[]> plaintext(new unsigned char[length]);memcpy(plaintext.get(), outbuf, length);// Set expected tag valueEVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (void*)tag);// Finalise: note get no output for GCMint rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen);// Print out return value. If this is not successful authentication failed and plaintext is not trustworthy.fprintf(stdout, "Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!");EVP_CIPHER_CTX_free(ctx);return plaintext;
}} // namespaceint main()
{fprintf(stdout, "Start AES GCM 256 Encrypt:\n");const char* plaintext = "1234567890ABCDEFG!@#$%^&*()_+[]{};':,.<>/?|";fprintf(stdout, "src plaintext: %s, length: %d\n", plaintext, strlen(plaintext));int length = 0;std::unique_ptr<unsigned char[]> tag(new unsigned char[16]);std::unique_ptr<unsigned char[]> ciphertext = aes_gcm_encrypt(plaintext, length, tag.get());fprintf(stdout, "length: %d, ciphertext: ", length);for (int i = 0; i < length; ++i)fprintf(stdout, "%02x ", ciphertext.get()[i]);fprintf(stdout, "\nTag: ");for (int i = 0; i < 16; ++i)fprintf(stdout, "%02x ", tag.get()[i]);fprintf(stdout, "\n");fprintf(stdout, "\nStart AES GCM 256 Decrypt:\n");std::unique_ptr<unsigned char[]> result = aes_gcm_decrypt(ciphertext.get(), length, tag.get());fprintf(stdout, "length: %d, decrypted plaintext: ", length);for (int i = 0; i < length; ++i)fprintf(stdout, "%c", result.get()[i]);fprintf(stdout, "\n");if (strncmp(plaintext, (const char*)result.get(), length) == 0) {fprintf(stdout, "decrypt success\n");return 0;}fprintf(stderr, "decrypt fail\n");return -1;
}
? ? ? (4).CMakeLists.txt文件內(nèi)容如下:
cmake_minimum_required(VERSION 3.12)
project(test_openssl)add_definitions("-std=c++11")include(${CMAKE_CURRENT_SOURCE_DIR}/build/conanbuildinfo.cmake)
include_directories(${CONAN_INCLUDE_DIRS_OPENSSL})
link_directories(${CONAN_LIB_DIRS_OPENSSL})add_executable(main main.cpp)
target_link_libraries(main ${CONAN_LIBS_OPENSSL})
? ? ? (5).依次執(zhí)行如下命令:
cmake ..
make
./main
? ? ? 執(zhí)行結(jié)果如下圖所示:
? ? ? GitHub:https://github.com/fengbingchun/Linux_Code_Test
總結(jié)
以上是生活随笔為你收集整理的Conan客户端简单使用示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++包管理工具Conan简介
- 下一篇: 深度神经网络中的Batch Normal