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. magento 用程序生成优惠劵码

    参考自http://fragmentedthought.com/fragments/programatically-creating-sales-rule-coupon-code 上面的代码只能生成C ...

  2. JAVA面试题最全集

      JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基 ...

  3. oracle (DBaaS) 服务介绍

    转 https://oracle-base.com/articles/vm/oracle-cloud-database-as-a-service-dbaas-create-service?utm_so ...

  4. Windows API函数大全一

    1. API之网络函数             WNetAddConnection 创建同一个网络资源的永久性连接             WNetAddConnection2 创建同一个网络资源的连 ...

  5. SQL常用自定义函数

    1.字符串转Table(Func_SplitToTable) CREATE FUNCTION [dbo].[Func_SplitToTable]      (        @SplitString ...

  6. Toast解析

    课程Demo public class MainActivity extends AppCompatActivity { private Button bt1; private Button bt2; ...

  7. greendao3.2.3配置时遇到的问题

    这两天我一直在研究greendao这个框架,我在GitHub下载了 greendao3.2.2:https://github.com/greenrobot/greenDAO,照着网址里面来配置: // ...

  8. git --删除文件、重命名

    修改最后一次提交 git commit --amend -m “” 删除文件:. git rm <需要删除的文件> 只是删除当前工作目录和暂存区的文件,也就是取消跟踪.在下次提交时不纳入版 ...

  9. Redis缓存Object,List对象

    一.到目前为止(jedis-2.2.0.jar),在Jedis中其实并没有提供这样的API对对象,或者是List对象的直接缓存,即并没有如下类似的API jedis.set(String key, O ...

  10. Which dispatch method would be used in Swift?-Existential Container

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...