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;
}