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函数的使用的更多相关文章

  1. openssl之EVP系列之13---EVP_Open系列函数介绍

    openssl之EVP系列之13---EVP_Open系列函数介绍     ---依据openssl doc/crypto/EVP_OpenInit.pod翻译和自己的理解写成     (作者:Dra ...

  2. openssl之EVP系列之9---EVP_Digest系列函数的一个样例

    openssl之EVP系列之9---EVP_Digest系列函数的一个样例     ---依据openssl doc/crypto/EVP_DigestInit.pod翻译     (作者:Drago ...

  3. openssl之EVP系列之8---EVP_Digest系列函数具体解释

    openssl之EVP系列之8---EVP_Digest系列函数具体解释     ---依据openssl doc/crypto/EVP_DigestInit.pod翻译和自己的理解写成     (作 ...

  4. openssl之EVP系列之12---EVP_Seal系列函数介绍

    openssl之EVP系列之12---EVP_Seal系列函数介绍     ---依据openssl doc/crypto/EVP_SealInit.pod翻译和自己的理解写成     (作者:Dra ...

  5. openssl之EVP系列之11---EVP_Verify系列函数介绍

    openssl之EVP系列之11---EVP_Verify系列函数介绍     ---依据openssl doc/crypto/EVP_VerifyInit.pod翻译和自己的理解写成     (作者 ...

  6. openssl之EVP系列之10---EVP_Sign系列函数介绍

    openssl之EVP系列之10---EVP_Sign系列函数介绍     ---依据openssl doc/crypto/EVP_SignInit.pod翻译     (作者:DragonKing, ...

  7. openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)

    openssl之EVP系列之5---EVP_Encrypt系列函数详细解释(二)    ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay.t ...

  8. openssl之EVP系列之1---算法封装

    openssl之EVP系列之1---算法封装     ---依据openssl doc/crypto/EVP.pod翻译和自己的理解写成     (作者:DragonKing, Mail: wzhah ...

  9. openssl之EVP系列之7---信息摘要算法结构概述

    openssl之EVP系列之7---信息摘要算法结构概述     ---依据openssl doc/crypto/EVP_DigestInit.pod翻译和自己的理解写成     (作者:Dragon ...

随机推荐

  1. Ubuntu install and uinstall

    一.Ubuntu中软件安装方法 1.APT方式 (1)普通安装:apt-get install softname1 softname2 -; (2)修复安装:apt-get -f install so ...

  2. ACM数论-求组合数

    我们利用这个公式求阶乘和逆元求阶: #include<cstdio> const int N = 200000 + 5; const int MOD = (int)1e9 + 7; int ...

  3. C#画图——Graphics

    C#要实现简单的画图功能可以利用Graphics这个类,要使用Graphics必需using命名空间System.Drawing(此名明空间下都是关于图形的操作).首先创建画布: Bitmap bmp ...

  4. B. Hongcow Solves A Puzzle

    http://codeforces.com/contest/745/problem/B 题目要求的是,给定一个图形,要求里面判断是否有矩形,且仅有一个 就是 XXX.... XXX...X 是不行的, ...

  5. 转】用Mahout构建职位推荐引擎

    原博文出自于: http://blog.fens.me/hadoop-mahout-recommend-job/ 感谢! 用Mahout构建职位推荐引擎 Hadoop家族系列文章,主要介绍Hadoop ...

  6. js基础 -----鼠标事件(按下 拖拽)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. windows 安装绿色版mysql

    (1)到官网下载绿色版mysql:http://dev.mysql.com/downloads/mysql/ (2)下载好后,放在F:\mysql,解压出来 (3)进入到mysql-5.6.19-wi ...

  8. iOS-UI控件之UITableView(二)- 自定义不等高的cell

    不等高的cell 给模型增加frame数据 所有子控件的frame cell的高度 @interface XMGStatus : NSObject /**** 文字\图片数据 ****/ // ... ...

  9. [eclipse]的快捷键的设置

    今天新解压了一个eclipse,发现alt+/提示的快捷键不好用了,开始比较犯懒,但是发现开发效率低下,总结几个eclipse下快捷方式的解决办法. 第一个解决没有一点提示的情况. 1.首先通过菜单打 ...

  10. 从mysql全库备份中恢复指定库和指定表

    需求:开发要求导入某天某个表的数据,而我们的数据是全库备份 例如:  从newbei_2017-08-31_402793782.tar.bz2中恢复表:bei_table 的数据 一.备份策略 备份全 ...