openssl库使用
2020-07-18 03:56:09 # cpp

comm_crypto.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once

#include <memory>
#include <string>
#include <string_view>

namespace Sky::CommCrypto {
void md5(std::string_view value, std::string& res);

void sha1(std::string_view value, std::string& res);

void sha224(std::string_view value, std::string& res);

void sha256(std::string_view value, std::string& res);

void sha384(std::string_view value, std::string& res);

void sha512(std::string_view value, std::string& res);

void base64Encode(std::string_view value, bool newLine, std::string& res);

void base64Decode(std::string_view value, bool newLine, std::string& res);
} // namespace Sky::CommCrypto

comm_crypto.cpp

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "comm_crypto.h"

#include <cstring>

#include "logger.h"
#include "openssl/buffer.h"
#include "openssl/dh.h"
#include "openssl/evp.h"
#include "openssl/md5.h"
#include "openssl/sha.h"

namespace Sky {
#define SKY_GENERATE_OPEN_SSL(object, crypro_size, value, res, name) \
uint8_t digest[crypro_size]{}; \
char curHex[crypro_size * 2 + 1]{}; \
uint32_t len = value.size(); \
EVP_MD_CTX* ctx = EVP_MD_CTX_new(); \
if (EVP_DigestInit_ex(ctx, object, nullptr) != 1) { \
LOG_ERROR("CommCrypto::{} init value:{} error" name, value); \
return; \
} \
if (EVP_DigestUpdate(ctx, value.data(), len) != 1) { \
LOG_ERROR("CommCrypto::{} update value:{} error", name, value); \
return; \
} \
if (EVP_DigestFinal_ex(ctx, digest, &len) != 1) { \
LOG_ERROR("CommCrypto::{} final value:{} error", name, value); \
return; \
} \
EVP_MD_CTX_destroy(ctx); \
for (int i = 0; i < crypro_size; i++) { \
sprintf(&curHex[i * 2], "%02X", digest[i]); \
} \
res.assign(curHex);

void CommCrypto::md5(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::md5 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_md5(), MD5_DIGEST_LENGTH, value, res, "md5");
}

void CommCrypto::sha1(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::sha1 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_sha1(), SHA_DIGEST_LENGTH, value, res, "sha1");
}

void CommCrypto::sha224(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::sha224 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_sha224(), SHA224_DIGEST_LENGTH, value, res, "sha224");
}

void CommCrypto::sha256(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::sha256 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_sha256(), SHA256_DIGEST_LENGTH, value, res, "sha256");
}

void CommCrypto::sha384(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::sha384 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_sha384(), SHA384_DIGEST_LENGTH, value, res, "sha384");
}

void CommCrypto::sha512(std::string_view value, std::string& res) {
if (value.empty()) {
LOG_ERROR("CommCrypto::sha512 value empty");
return;
}

SKY_GENERATE_OPEN_SSL(EVP_sha512(), SHA512_DIGEST_LENGTH, value, res, "sha512");
}

void CommCrypto::base64Encode(std::string_view value, bool newLine, std::string& res) {
BUF_MEM* Ptr{};
BIO* base64 = BIO_new(BIO_f_base64());
if (!newLine) {
BIO_set_flags(base64, BIO_FLAGS_BASE64_NO_NL);
}

BIO* mem = BIO_new(BIO_s_mem());
base64 = BIO_push(base64, mem);
BIO_write(base64, value.data(), static_cast<int>(value.size()));
BIO_flush(base64);
BIO_get_mem_ptr(base64, &Ptr);
BIO_set_close(base64, BIO_NOCLOSE);

auto buffer = std::make_unique<char[]>(Ptr->length + 1);
memcpy(buffer.get(), Ptr->data, Ptr->length);
BIO_free_all(base64);

res.assign(buffer.get());
}

void CommCrypto::base64Decode(std::string_view value, bool newLine, std::string& res) {
if (value.empty()) {
return;
}

BIO* bese64 = BIO_new(BIO_f_base64());
if (!newLine) {
BIO_set_flags(bese64, BIO_FLAGS_BASE64_NO_NL);
}

BIO* mem = BIO_new_mem_buf(value.data(), static_cast<int>(value.size()));
mem = BIO_push(bese64, mem);
auto buffer = std::make_unique<char[]>(value.size());
BIO_read(mem, buffer.get(), static_cast<int>(value.size()));
BIO_free_all(mem);
res.assign(buffer.get());
}
} // namespace Sky