base64 编码: openssl enc -base64 -in plain.txt -out base64.txt
    enc: 通用加密指令
    -base64: 指定加密方式为 base64
    -in 文件名: 需要进行 base64 的文件
    -out 文件名: base64 后的文件保存到哪里
    -e(默认): 表示当前需要执行编码操作
base64 解码: openssl enc -d -base64 -in plain.txt -out base64.txt
    -d: 表示当前需要执行解码操作
查看 md5 输出到控制台: openssl dgst -md5 demo.exe
查看 md5 输出到文件中: openssl dgst -md5 -out md5.txt demo.exe
    -md5: 指定使用 md5 算法计算消息摘要,通过 help 查看支持的所有算法
对称加密: openssl enc -des-cbc -in demo.png -out encrypt.png -pass pass:12345678
    -des-cbc: 指定加密方式和分组模式,使用 help 查看所有
    -pass: 指定对称加密使用的 key
01. base64
#include <iostream>#include <openssl/bio.h>#include <openssl/buffer.h>#include <openssl/evp.h>#pragma comment(lib, "libcrypto.lib")// 1. 在项目属性的目录中添加 openssl 的 lib 和 include 路径// 2. 用到了什么东西就加上相应的头文件// 3. 必须需要链接到 libcrypto.lib 静态库// 要求传入一个需要加密的串,以及串的长度,参数三是否需要换行,返回编码后的数据char* Base64Encode(const char* input, int length, bool with_new_line){// 创建一个 base64 对象,对象的特点就是使用 write 写入的// 数据会被自动编码,使用 read 读取的数据会自动解码BIO* b64 = BIO_new(BIO_f_base64());// 默认编码之后存在换行符,通常不需要换行符if (!with_new_line)BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);// 再次创建了一个内存对象,对象的特点就是使用 write 写入的// 数据会自动保存到某一个缓冲区。BIO_push 将两个对象进行关// 联,也就是说传入的数据首先会进行 base64 编码,然后保存到// 缓冲区。b64 = BIO_push(b64, BIO_new(BIO_s_mem()));// 将传入的数据进行编码,BIO_flush 将操作刷新到对象BIO_write(b64, input, length);BIO_flush(b64);// 从 base64 对象中获取到相应的编码后的内容BUF_MEM* bptr = NULL;BIO_get_mem_ptr(b64, &bptr);// 将编码后的数据拷贝到指定的位置char* b64encode = new char[bptr->max]{};memcpy(b64encode, bptr->data, bptr->max);// 清理 BIO 对象,并返回结果BIO_free_all(b64);return b64encode;}char* Base64Decode(char* input, int length, bool with_new_line){BIO* b64 = BIO_new(BIO_f_base64());if (!with_new_line)BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);// 编码后的长度和原文大概比例是 4:3,使用编码后的长度// 进行解码,空间是绝对足够的char* buffer = (char*)malloc(length);if (buffer) memset(buffer, 0, length);// 创建一个内存对象,存入编码后的内容,并关联到 base64 对象BIO* bmem = BIO_push(b64, BIO_new_mem_buf(input, length));// 对 base64 read 就是解码数据BIO_read(bmem, buffer, length);// 清理并返回原文BIO_free_all(bmem);return buffer;}int main(){auto b64e = Base64Encode("hello15pbo", 10, false);printf("b64e: %s\n", b64e);auto b64d = Base64Decode(b64e, strlen(b64e), false);printf("b64d: %s\n", b64d);return 0;}
02. md
#include <iostream>using namespace std;#include <openssl/md5.h>#include <openssl/sha.h>#pragma comment(lib, "libcrypto.lib")int md5_encrypt(const void* data, size_t len, unsigned char* md5){// 初始化保存 md5 信息的结构体MD5_CTX ctx = { 0 };MD5_Init(&ctx);// 将需要计算的数据传入到对应的结构中MD5_Update(&ctx, data, len);// 从结构中获取计算后的结果MD5_Final(md5, &ctx);return 0;}int sha1_encrypt(const void* data, size_t len, unsigned char* md5){SHA_CTX ctx = { 0 };SHA1_Init(&ctx);SHA1_Update(&ctx, data, len);SHA1_Final(md5, &ctx);return 0;}int sha256_encrypt(const void* data, size_t len, unsigned char* md5){SHA256_CTX ctx = { 0 };SHA256_Init(&ctx);SHA256_Update(&ctx, data, len);SHA256_Final(md5, &ctx);return 0;}void show_hex(const char* n, unsigned char* hex, size_t length){printf(n);for (int i = 0; i < length; ++i)printf("%02X", hex[i]);printf("\n");}int main(){unsigned char hex[100] = { 0 };md5_encrypt("hello15pb", 9, hex);show_hex("md5: ", hex, 16);sha1_encrypt("hello15pb", 9, hex);show_hex("sha1: ", hex, 20);sha256_encrypt("hello15pb", 9, hex);show_hex("sha256: ", hex, 32);return 0;}
03. aes
#include <iostream>#include <openssl/evp.h>#pragma comment(lib, "libcrypto.lib")// 返回值是加密后的密文长度,传入明文,明文长度和保存密文的缓冲区int evp_en_cipher(unsigned char* source_string, unsigned char* des_string, int length){// 创建一个通用加解密的对象,设置填充方式EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();EVP_CIPHER_CTX_set_padding(ctx, 1);// once_length 是一次加密的长度, out_length 加密后密文的长度int once_length = 0, out_length = 0;// 设置加密时使用的算法+分组模式和 key,函数的倒数第二个参数可以// 用于指定初始化向量,最后一个参数是 1 表示加密,否则解密unsigned char key[16] = "15pb";EVP_CipherInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, nullptr, 1);// 使用 EVP_CipherUpdate + EVP_CipherFinal 完成整个加密EVP_CipherUpdate(ctx, des_string, &once_length, source_string, length);out_length += once_length;EVP_CipherFinal(ctx, des_string + once_length, &once_length);out_length += once_length;// 清理对象并返回长度EVP_CIPHER_CTX_free(ctx);return out_length;}int evp_de_cipher(unsigned char* source_string, unsigned char* des_string, int length){EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new();EVP_CIPHER_CTX_set_padding(ctx, 1);int once_length = 0, out_length = 0;// 解密的代码和加密除 EVP_CipherInit_ex 的最后一个参数外基本相同unsigned char key[16] = "15pb";EVP_CipherInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, nullptr, 0);EVP_CipherUpdate(ctx, des_string, &once_length, source_string, length);out_length += once_length;EVP_CipherFinal(ctx, des_string + once_length, &once_length);out_length += once_length;// 为加密后的数据添加空字符des_string[out_length] = 0;EVP_CIPHER_CTX_free(ctx);return out_length;}int main(int argc, char* argv[]){unsigned char planttext[] ="123456789123456789""123456789123456789""123456789123456789""123456789123456789""123456789123456789""123456789123456789";unsigned char temp_string[1000] = { 0 };int en_length = evp_en_cipher(planttext, temp_string, 108);int de_length = evp_de_cipher(temp_string, temp_string, en_length);printf("%s", temp_string);return 0;}
