关于OPENSSL的EVP函数的使用
4月份没什么做,就是做了OPENSSL的 加密和解密的应用,现在公开一下如何调用OPENSSL对字符串进行加密和解密,当中也学会了对加密数据进行BASE64编码,现在公开一下代码,在这感谢GITHUB里的好心人
//加密例子
int encryptdate(string plaindatas, string & encryptedatas)
{
const unsigned char iv[8] = { '1', '2', '3', '4, '5', '6', '7', '8' };
const unsigned char key[8] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
const unsigned char * in = reinterpret_cast<const unsigned char *> (plaindatas.c_str());
int written = 0, temp;
unsigned char * outbuf = new unsigned char[plaindatas.length()+1];
int in_len = plaindatas.length();
EVP_CIPHER_CTX *ctx;
if (!(ctx = EVP_CIPHER_CTX_new()))
{
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
return -1;
}
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_cbc(), NULL, key, iv))
{
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_EncryptInit_ex failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);
if (1 != EVP_EncryptUpdate(ctx, outbuf, &temp, in, in_len))
{
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_EncryptUpdate failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
written = temp;
if (1 != EVP_EncryptFinal_ex(ctx, outbuf + temp, &temp))
{
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_EncryptFinal_ex failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
written += temp;
//EVP_CIPHER_CTX_free(ctx);
EVP_CIPHER_CTX_cleanup(ctx);
encryptedatas = base64_encode(outbuf, written);
return 0;
}
//解密
int decryptdate(string encryptdatas, string & decryptdatas)
{
const unsigned char iv[8] = { '1', '2', '3', '4, '5', '6', '7', '8' };
const unsigned char key[8] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
string decordstr = my_base64_decode(encryptdatas);
EVP_CIPHER_CTX * ctx;
int len=0;
int plaintext_len=0;
int ciphertext_len = decordstr.length();
unsigned char * ciphertext = new unsigned char[ciphertext_len]; //这个size 要大于 str.size();
memcpy(ciphertext, &decordstr[0], decordstr.size());
unsigned char * plaintext = new unsigned char[ciphertext_len];
/* Create and initialise the context */
if (!(ctx = EVP_CIPHER_CTX_new())) {
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
// EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
/* Initialise the decryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_cbc(), NULL, key, iv)){
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_DecryptInit_ex failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)){
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_DecryptUpdate failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
plaintext_len = len;
/* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)){
string errstr = ERR_error_string(ERR_get_error(), NULL);
errstr = "ERROR: EVP_DecryptFinal_ex failed. OpenSSL error:" + errstr;
write_text_to_log_file(errstr);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
plaintext_len += len;
plaintext[plaintext_len] = 0;
decryptdatas = (reinterpret_cast<char const *>(plaintext));
/* Clean up */
EVP_CIPHER_CTX_cleanup(ctx);
return 0;
}
而base64的代码如下,我测试过可行
//编码
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i <4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
//base64解码
#include <cassert>
#include <limits>
#include <stdexcept>
#include <cctype>
static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char reverse_table[128] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 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, 64, 64, 64, 64, 64,
64, 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, 64, 64, 64, 64, 64
};
::std::string my_base64_decode(const ::std::string &ascdata)
{
using ::std::string;
string retval;
const string::const_iterator last = ascdata.end();
int bits_collected = 0;
unsigned int accumulator = 0;
for (string::const_iterator i = ascdata.begin(); i != last; ++i) {
const int c = *i;
if (::std::isspace(c) || c == '=') {
// Skip whitespace and padding. Be liberal in what you accept.
continue;
}
if ((c > 127) || (c < 0) || (reverse_table[c] > 63)) {
throw ::std::invalid_argument("This contains characters not legal in a base64 encoded string.");
}
accumulator = (accumulator << 6) | reverse_table[c];
bits_collected += 6;
if (bits_collected >= 8) {
bits_collected -= 8;
retval += static_cast<char>((accumulator >> bits_collected) & 0xffu);
}
}
return retval;
}
关于OPENSSL的EVP函数的使用的更多相关文章
- openssl之EVP系列之13---EVP_Open系列函数介绍
openssl之EVP系列之13---EVP_Open系列函数介绍 ---依据openssl doc/crypto/EVP_OpenInit.pod翻译和自己的理解写成 (作者:Dra ...
- openssl之EVP系列之9---EVP_Digest系列函数的一个样例
openssl之EVP系列之9---EVP_Digest系列函数的一个样例 ---依据openssl doc/crypto/EVP_DigestInit.pod翻译 (作者:Drago ...
- openssl之EVP系列之8---EVP_Digest系列函数具体解释
openssl之EVP系列之8---EVP_Digest系列函数具体解释 ---依据openssl doc/crypto/EVP_DigestInit.pod翻译和自己的理解写成 (作 ...
- openssl之EVP系列之12---EVP_Seal系列函数介绍
openssl之EVP系列之12---EVP_Seal系列函数介绍 ---依据openssl doc/crypto/EVP_SealInit.pod翻译和自己的理解写成 (作者:Dra ...
- openssl之EVP系列之11---EVP_Verify系列函数介绍
openssl之EVP系列之11---EVP_Verify系列函数介绍 ---依据openssl doc/crypto/EVP_VerifyInit.pod翻译和自己的理解写成 (作者 ...
- openssl之EVP系列之10---EVP_Sign系列函数介绍
openssl之EVP系列之10---EVP_Sign系列函数介绍 ---依据openssl doc/crypto/EVP_SignInit.pod翻译 (作者:DragonKing, ...
- openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)
openssl之EVP系列之5---EVP_Encrypt系列函数详细解释(二) ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay.t ...
- openssl之EVP系列之1---算法封装
openssl之EVP系列之1---算法封装 ---依据openssl doc/crypto/EVP.pod翻译和自己的理解写成 (作者:DragonKing, Mail: wzhah ...
- openssl之EVP系列之7---信息摘要算法结构概述
openssl之EVP系列之7---信息摘要算法结构概述 ---依据openssl doc/crypto/EVP_DigestInit.pod翻译和自己的理解写成 (作者:Dragon ...
随机推荐
- 牛客网暑期ACM多校训练营(第五场)
J-plan(贪心) 题目描述 There are n students going to travel. And hotel has two types room:double room and t ...
- Activity状态图、生命周期图(超详细),onSaveInstanceState只保存、恢复基本ui数据,持久数据不在这里保存。
1.Activity状态图 2.Activity生命周期简图 启动Activity: onCreate()—>onStart()—>onResume(),Activity进入running ...
- Saas物联网共享平台实战
什么是SaaS系统: 越来越多的软件,开始采用云服务. 云服务只是一个统称,可以分成三大类. IaaS:基础设施服务,Infrastructure-as-a-service PaaS:平台服务,Pla ...
- 帮助新手理解equals和hashCode
入行快要两年,偶尔想起来equals和hash还是会有些晕,索性今天就更深入的弄明白一些,不足之处也请各位大神指出批评,共同进步. 刚开始学java的时候只是记忆性的来背,如果一个类在程序中可能进行比 ...
- mysql之通过cmd连接远程数据库
---恢复内容开始--- 目录 前提 连接远程数据库 前提: 本地安装了mysql数据库 本地和远程网络是连通的,通过命令ping ip (即ping 192.168.0.333),可以ping通 连 ...
- mysql之修改字符编码
目录 统一修改字段编码 修改单个字段编码 修改表字符编码 统一修改字段编码: alter table `tablename` convert to character set utf8; 修改表字符编 ...
- hihocoder编程练习赛52-3 部门聚会
思路: 树形dp. 实现: #include <bits/stdc++.h> using namespace std; ; int n, a[MAXN], in[MAXN]; vector ...
- Linux 时间同步 ntpdate
ntpdate 使用网络计时协议(NTP)设置日期和时间.此命令仅应用于 AIX 4.2 或后期版本. 语法: ntpdate [ -b] [ -d] [ -s] [ -u] [ -aKeyid] [ ...
- com口操作excel
_Application app; //Excel应用程序接口 Workbooks books; //工作薄集合 _Workbook book; //工作薄 Work ...
- idea文件全部变红, 文件全部红色
idea如果当前project用了版本控制器,其下面新建的所有的项目默认都是加入到版本控制里面,所以项目名称和文件都是红色的,如图: 看起来非常不爽, 那么如何解决呢? File–>Settin ...