VC++使用OpenSSL库实现字符串md5(base64)加密

1 背景

最近在一个项目中遇到这样一种情况,服务器(JAVA)后台需要校验用户名和密码,采用的方式是md5(base64)的加密方式,例如:将字符串"zhangsan:123456"采用md5(base64)加密,目标结果如下

md5(base64)实际上就是将String型的字符串先经过md5摘要加密,得到byte[]型的数据,再将byte[]型的数据以base64的编码输出。其JAVA实现方式如下:

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import sun.misc.BASE64Encoder;
import java.security.MessageDigest;

public class java_md5_base64 {

	public static String md5_base64(String data) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest md = MessageDigest.getInstance("MD5");
		md.update(data.getBytes());
		byte[] pass = md.digest();

		BASE64Encoder encoder = new BASE64Encoder();
		String encryData = encoder.encode(pass);
		return encryData;
	}
}

现在客户端要用C++的方式来实现,乍一看md5(base64)无非就是先md5加密再base64编码输出嘛,很简单,算法网上都有,直接参考。可结果咋总不对呢?原因是忽略了一个细节,“md5摘要加密,得到byte[]型的数据”,而不是字符串。网上诸多在线md5加密工具,或者是md5加密算法源码,得到的是字符串,而且有16位、32位、大写小写之分,再进行base64编码,固然与目标结果千差万别。

  • 16位小写Base64编码:ODJhYjI5NGVhNjE5ZDJmNQ==
  • 16位大写Base64编码:ODJBQjI5NEVBNjE5RDJGNQ==
  • 32位小写Base64编码:NGNhOGFlZTE4MmFiMjk0ZWE2MTlkMmY1YTAyNTdjZDk=
  • 32位大写Base64编码:NENBOEFFRTE4MkFCMjk0RUE2MTlEMkY1QTAyNTdDRDk=

在这里,为简化操作本文直接采用强大的OpenSSL库来实现

2 VC++使用OpenSSL库

2.1 OpenSSL库下载安装

http://slproweb.com/products/Win32OpenSSL.html下载Win32 OpenSSL v1.1.1,并安装,这里直接默认安装路径为C:\Program Files (x86)\OpenSSL-Win32。

2.2 VS加入OpenSSL库

工程目录新建文件夹openssl,openssl下新建目录include和lib目录。

将lib\VC下的库文件拷贝到工程目录openssl\lib。

将include\openssl下的所有头文件拷贝到工程目录openssl\include。

将bin下的libcrypto-1_1.dll拷贝到工程运行程序下。

库文件和头文件添加到工程源码这里就不做赘述了,直接上码。

2.3 md5(base64)加密字符串

包含OpenSSL头文件

#include "md5.h"
#include "evp.h"
#include "bio.h"
#include "buffer.h"

base64编码

std::string base64Encode(const char * input, int length, bool with_new_line)
{

	BIO * bmem = NULL;
	BIO * b64 = NULL;
	BUF_MEM * bptr = NULL;

	b64 = BIO_new(BIO_f_base64());

	if(!with_new_line) {
		BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	}

	bmem = BIO_new(BIO_s_mem());
	b64 = BIO_push(b64, bmem);
	BIO_write(b64, input, length);
	BIO_flush(b64);
	BIO_get_mem_ptr(b64, &bptr);

	char * buff = (char *)malloc(bptr->length + 1);
	memcpy(buff, bptr->data, bptr->length);
	buff[bptr->length] = 0;

	BIO_free_all(b64);

	return buff;
}

md5(base64)加密

void md5Base64(std::string &str)
{
	std::string md5Str;
        md5Str.clear();

	MD5_CTX ctx;

	unsigned char md[MD5_DIGEST_LENGTH];
	memset(&ctx,0,sizeof(MD5_CTX));
	memset(md,0,sizeof(md));

	MD5_Init(&ctx);
	MD5_Update(&ctx,str.c_str(),str.size());

	MD5_Final(md,&ctx);

	md5Str = (char*)md;

	str = base64Encode(md5Str.c_str(), md5Str.size(), false);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值