关于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 ...
随机推荐
- magento 用程序生成优惠劵码
参考自http://fragmentedthought.com/fragments/programatically-creating-sales-rule-coupon-code 上面的代码只能生成C ...
- JAVA面试题最全集
JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基 ...
- oracle (DBaaS) 服务介绍
转 https://oracle-base.com/articles/vm/oracle-cloud-database-as-a-service-dbaas-create-service?utm_so ...
- Windows API函数大全一
1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连 ...
- SQL常用自定义函数
1.字符串转Table(Func_SplitToTable) CREATE FUNCTION [dbo].[Func_SplitToTable] ( @SplitString ...
- Toast解析
课程Demo public class MainActivity extends AppCompatActivity { private Button bt1; private Button bt2; ...
- greendao3.2.3配置时遇到的问题
这两天我一直在研究greendao这个框架,我在GitHub下载了 greendao3.2.2:https://github.com/greenrobot/greenDAO,照着网址里面来配置: // ...
- git --删除文件、重命名
修改最后一次提交 git commit --amend -m “” 删除文件:. git rm <需要删除的文件> 只是删除当前工作目录和暂存区的文件,也就是取消跟踪.在下次提交时不纳入版 ...
- Redis缓存Object,List对象
一.到目前为止(jedis-2.2.0.jar),在Jedis中其实并没有提供这样的API对对象,或者是List对象的直接缓存,即并没有如下类似的API jedis.set(String key, O ...
- Which dispatch method would be used in Swift?-Existential Container
In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...