1. 程式人生 > >基於Openssl的base64字串轉string

基於Openssl的base64字串轉string

在上一篇文章寫到過,aes加密過的文字控制檯程式是沒有辦法識別的,這樣就導致了控制檯程式沒辦法打印出字串,因此需要將base64的字串轉碼,所以這裡就實現base64轉碼

Base64.h檔案

#pragma once
#ifndef ENCRYPTDEMO_CBASE64_H
#define ENCRYPTDEMO_CBASE64_H

#include <stdio.h>
#include <string>

typedef struct evp_Encode_Ctx_st {
	/* number saved in a partial encode/decode */
	int num;
	/*
	* The length is either the output line length (in input bytes) or the
	* shortest input line length that is ok.  Once decoding begins, the
	* length is adjusted up each time a longer line is decoded
	*/
	int length;
	/* data to encode */
	unsigned char enc_data[80];
	/* number read on current line */
	int line_num;
	int expect_nl;
} EVP_ENCODE_CTX;

class CBase64
{
public:
	static std::string base64_decode(const std::string& encoded_bytes,int *decoded_length);
	static std::string base64_encode(const std::string& decoded_bytes,size_t decoded_length);
	static std::string base64_encodestring(const std::string &text);
	static std::string base64_decodestring(const std::string &text);
};


#endif //ENCRYPTDEMO_CBASE64_H

CBase64.app檔案

#include "stdafx.h"
#include "Base64.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/bio.h>
#include <openssl/ossl_typ.h>

std::string CBase64::base64_encodestring(const std::string &text) {
	EVP_ENCODE_CTX ectx;
	int size = text.size() * 2;
	size = size > 64 ? size : 64;
	unsigned char* out = (unsigned char*)malloc(size);
	int outlen = 0;
	int tlen = 0;
	EVP_EncodeInit(&ectx);
	EVP_EncodeUpdate(&ectx, out, &outlen, (const unsigned char*)text.c_str(), text.size());
	tlen += outlen;
	EVP_EncodeFinal(&ectx, out + tlen, &outlen);
	tlen += outlen;

	std::string str((char*)out, tlen);
	free(out);
	return str;
}

std::string CBase64::base64_decodestring(const std::string &text) {
	EVP_ENCODE_CTX ectx;
	unsigned char* out = (unsigned char*)malloc(text.size());
	int outlen = 0;
	int tlen = 0;

	EVP_DecodeInit(&ectx);
	EVP_DecodeUpdate(&ectx, out, &outlen, (const unsigned char*)text.c_str(), text.size());
	tlen += outlen;
	EVP_DecodeFinal(&ectx, out + tlen, &outlen);
	tlen += outlen;

	std::string data((char*)out, tlen);
	free(out);
	return data;
}

std::string CBase64::base64_decode(const std::string& encoded_bytes, int *decoded_length) {
	BIO *bioMem, *b64;
	size_t buffer_length;

	bioMem = BIO_new_mem_buf((void *)encoded_bytes.c_str(), -1);
	b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bioMem = BIO_push(b64, bioMem);

	buffer_length = BIO_get_mem_data(bioMem, NULL);

	static std::string  decoded_bytes;

	decoded_bytes.clear();

	*decoded_length = BIO_read(bioMem, (void *)decoded_bytes.c_str(), (int)buffer_length);
	BIO_free_all(bioMem);

	return  decoded_bytes;
}

/* Return NULL if failed, REMEMBER to free() */
std::string CBase64::base64_encode(const std::string& decoded_bytes,

	size_t decoded_length) {
	int x;
	BIO *bioMem, *b64;
	BUF_MEM *bufPtr;
	static std::string buff;
	buff.clear();

	b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bioMem = BIO_new(BIO_s_mem());
	b64 = BIO_push(b64, bioMem);

	BIO_write(b64, decoded_bytes.c_str(), (int)decoded_length);
	x = BIO_flush(b64);
	if (x < 1)
		goto END;

	BIO_get_mem_ptr(b64, &bufPtr);

	buff.assign(bufPtr->data);

END: BIO_free_all(b64);
	return buff;
}

最後我們來看看怎麼實現的效果如何,用上一篇文章的程式碼來測試一下效果


  #include "stdafx.h"
  #include <string>
  #include <iostream>
  #include "Base64.h"
  #include "AES.h"
  #include <openssl/aes.h>  
 
int main()
{
	std::string aes_key("helloaeshelloaes", 16);
	std::string soure = "Hello World!!";
	std::string encrypt = CBase64::base64_encodestring(CAES::aes_128_ecb_encrypt(soure, aes_key));
	std::cout << "AES加密:" + encrypt << std::endl;
	std::string decrypt = CAES::aes_128_ecb_decrypt(CBase64::base64_decodestring(encrypt), aes_key);
	std::cout << "AES解密:" + decrypt << std::endl;
	system("pause");
	return 0;
}


效果如下所示: