原文地址找不到了

#include <windows.h>
#include <iostream>
#include <cassert>
#include <string>
#include <vector>
#include "openssl/md5.h"
#include "openssl/sha.h"
#include "openssl/des.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"

#include "utils.h"
#include<string.h>

#ifdef WIN32
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")
#endif

// ---- md5摘要哈希 ---- //
void md5(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
{
// 调用md5哈希
unsigned char mdStr[33] = {0};
MD5((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);

// 哈希后的字符串
encodedStr = std::string((const char *)mdStr);
// 哈希后的十六进制串 32字节
char buf[65] = {0};
char tmp[3] = {0};
for (int i = 0; i < 32; i++)
{
sprintf(tmp, "%02x", mdStr[i]);
strcat(buf, tmp);
}
buf[32] = '\0'; // 后面都是0,从32字节截断
encodedHexStr = std::string(buf);
}

// ---- sha256摘要哈希 ---- //
void sha256(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
{
// 调用sha256哈希
unsigned char mdStr[33] = {0};
SHA256((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);

// 哈希后的字符串
encodedStr = std::string((const char *)mdStr);
// 哈希后的十六进制串 32字节
char buf[65] = {0};
char tmp[3] = {0};
for (int i = 0; i < 32; i++)
{
sprintf(tmp, "%02x", mdStr[i]);
strcat(buf, tmp);
}
buf[32] = '\0'; // 后面都是0,从32字节截断
encodedHexStr = std::string(buf);
}

// ---- des对称加解密 ---- //
// 加密 ecb模式
std::string des_encrypt(const std::string &clearText, const std::string &key)
{
std::string cipherText; // 密文

DES_cblock keyEncrypt;
memset(keyEncrypt, 0, 8);

// 构造补齐后的密钥
if (key.length() <= 8)
memcpy(keyEncrypt, key.c_str(), key.length());
else
memcpy(keyEncrypt, key.c_str(), 8);

// 密钥置换
DES_key_schedule keySchedule;
DES_set_key_unchecked(&keyEncrypt, &keySchedule);

// 循环加密,每8字节一次
const_DES_cblock inputText;
DES_cblock outputText;
std::vector<unsigned char> vecCiphertext;
unsigned char tmp[8];

for (int i = 0; i < clearText.length() / 8; i++)
{
memcpy(inputText, clearText.c_str() + i * 8, 8);
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);

for (int j = 0; j < 8; j++)
vecCiphertext.push_back(tmp[j]);
}

if (clearText.length() % 8 != 0)
{
int tmp1 = clearText.length() / 8 * 8;
int tmp2 = clearText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, clearText.c_str() + tmp1, tmp2);
// 加密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
memcpy(tmp, outputText, 8);

for (int j = 0; j < 8; j++)
vecCiphertext.push_back(tmp[j]);
}

cipherText.clear();
cipherText.assign(vecCiphertext.begin(), vecCiphertext.end());

return cipherText;
}

// 解密 ecb模式
std::string des_decrypt(const std::string &cipherText, const std::string &key)
{
std::string clearText; // 明文

DES_cblock keyEncrypt;
memset(keyEncrypt, 0, 8);

if (key.length() <= 8)
memcpy(keyEncrypt, key.c_str(), key.length());
else
memcpy(keyEncrypt, key.c_str(), 8);

DES_key_schedule keySchedule;
DES_set_key_unchecked(&keyEncrypt, &keySchedule);

const_DES_cblock inputText;
DES_cblock outputText;
std::vector<unsigned char> vecCleartext;
unsigned char tmp[8];

for (int i = 0; i < cipherText.length() / 8; i++)
{
memcpy(inputText, cipherText.c_str() + i * 8, 8);
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);

for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}

if (cipherText.length() % 8 != 0)
{
int tmp1 = cipherText.length() / 8 * 8;
int tmp2 = cipherText.length() - tmp1;
memset(inputText, 0, 8);
memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
// 解密函数
DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
memcpy(tmp, outputText, 8);

for (int j = 0; j < 8; j++)
vecCleartext.push_back(tmp[j]);
}

clearText.clear();
clearText.assign(vecCleartext.begin(), vecCleartext.end());

return clearText;
}

// ---- rsa非对称加解密 ---- //
#define KEY_LENGTH 2048 // 密钥长度
#define PUB_KEY_FILE "pubkey.pem" // 公钥路径
#define PRI_KEY_FILE "prikey.pem" // 私钥路径
#define MAXPATH 1024

// 函数方法生成密钥对
void generateRSAKey(std::string strKey[2], char * key_pri_path)
{
// 公私密钥对
size_t pri_len;
size_t pub_len;
char *pri_key = NULL;
char *pub_key = NULL;
char path[MAXPATH] = {0};
char pub_path[MAXPATH] = {0};
char *p = NULL;

p = strrchr(key_pri_path, '/');
if(p){
memcpy(path, key_pri_path, (p - key_pri_path));
}else{
strcpy(path, ".");
}

//printf("path == %s\n", path);
CreateDirEx(path);

sprintf(pub_path, "%s/pub_%s", path, p+1);

// 生成密钥对
RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);

BIO *pri = BIO_new(BIO_s_mem());
BIO *pub = BIO_new(BIO_s_mem());

PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
PEM_write_bio_RSAPublicKey(pub, keypair);

// 获取长度
pri_len = BIO_pending(pri);
pub_len = BIO_pending(pub);

// 密钥对读取到字符串
pri_key = (char *)malloc(pri_len + 1);
pub_key = (char *)malloc(pub_len + 1);

BIO_read(pri, pri_key, pri_len);
BIO_read(pub, pub_key, pub_len);

pri_key[pri_len] = '\0';
pub_key[pub_len] = '\0';

// 存储密钥对
strKey[0] = pub_key;
strKey[1] = pri_key;

// 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)
FILE *pubFile = fopen(pub_path, "w");
if (pubFile == NULL)
{
assert(false);
return;
}
fputs(pub_key, pubFile);
fclose(pubFile);

FILE *priFile = fopen(key_pri_path, "w");
if (priFile == NULL)
{
assert(false);
return;
}
fputs(pri_key, priFile);
fclose(priFile);

// 内存释放
RSA_free(keypair);
BIO_free_all(pub);
BIO_free_all(pri);

free(pri_key);
free(pub_key);
}

// 命令行方法生成公私钥对(begin public key/ begin private key)
// 找到openssl命令行工具,运行以下
// openssl genrsa -out prikey.pem 1024
// openssl rsa - in privkey.pem - pubout - out pubkey.pem

// 公钥加密
std::string rsa_pub_encrypt(const std::string &clearText, const std::string &pubKey)
{
std::string strRet;
RSA *rsa = NULL;
BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
//RSA* pRSAPublicKey = RSA_new();
rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);

int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);

// 加密函数
int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);

// 释放内存
free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);

return strRet;
}

// 私钥加密
char * rsa_pri_encrypt(const unsigned char* clearText, int str_leng, unsigned char * priKey)
{
RSA *rsa = NULL;
BIO *keybio = BIO_new_mem_buf(priKey, -1);
// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
//RSA* pRSAPrivateKey = RSA_new();
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);

int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);

// 加密函数
int ret = RSA_private_encrypt(str_leng, (const unsigned char*)clearText, (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
/* if (ret >= 0)
printf("success\n");*/

// 释放内存
//free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);

return encryptedText;
}

// 公钥解密
char * rsa_pub_decrypt(const unsigned char* cipherText, int str_leng, unsigned char * pubKey)
{
RSA *rsa = RSA_new();

BIO *keybio;
keybio = BIO_new_mem_buf(pubKey, -1);

// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);

int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);

// 解密函数
int ret = RSA_public_decrypt(str_leng, (const unsigned char*)cipherText, (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
// if (ret >= 0)
// strRet = std::string(decryptedText, ret);

// 释放内存
// free(decryptedText);
BIO_free_all(keybio);
RSA_free(rsa);

return decryptedText;
}

// 私钥解密
std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
std::string strRet;
RSA *rsa = RSA_new();
BIO *keybio;
keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);

// 此处有三种方法
// 1, 读取内存里生成的密钥对,再从内存生成rsa
// 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
// 3,直接从读取文件指针生成rsa
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);

int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);

// 解密函数
int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);

// 释放内存
free(decryptedText);
BIO_free_all(keybio);
RSA_free(rsa);

return strRet;
}

int main111(int argc, char **argv)
{
// 原始明文
std::string srcText = "this is an example";
/* HMODULE hDllLib = LoadLibraryA("libssl-1_1.dll");
//HMODULE hDllLib = LoadLibraryA("mp110502.dll");

if (hDllLib)
{
std::cout << "=== 333333333333 ===" << std::endl;
}

*/
std::string encryptText;
std::string encryptHexText;
std::string decryptText;

std::cout << "=== 原始明文 ===" << std::endl;
std::cout << srcText << std::endl;

// md5
std::cout << "=== md5哈希 ===" << std::endl;
md5(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;

// sha256
std::cout << "=== sha256哈希 ===" << std::endl;
sha256(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;

// des
std::cout << "=== des加解密 ===" << std::endl;
std::string desKey = "12345";
encryptText = des_encrypt(srcText, desKey);
std::cout << "加密字符: " << std::endl;
std::cout << encryptText << std::endl;
decryptText = des_decrypt(encryptText, desKey);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;

// rsa
std::cout << "=== rsa加解密 ===" << std::endl;
std::string key[2];
generateRSAKey(key,"./");
std::cout << "公钥: " << std::endl;
std::cout << key[0] << std::endl;
std::cout << "私钥: " << std::endl;
std::cout << key[1] << std::endl;
encryptText = rsa_pub_encrypt(srcText, key[0]);
std::cout << "加密字符: " << std::endl;
std::cout << encryptText << std::endl;
decryptText = rsa_pri_decrypt(encryptText, key[1]);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;

system("pause");
return 0;
}

openssl md5 sha256 rsa des的更多相关文章

  1. C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)

    一:异或^简单加解密(数字类型) 1:原理: 异或用于比较两个二进制数的相应位,在执行按位"异或"运算时,如果两个二进制数的相应位都为1或者都为0,则返回0;如果两个二进制数的相应 ...

  2. C/C++使用openssl进行摘要和加密解密(md5, sha256, des, rsa)

    openssl里面有很多用于摘要哈希.加密解密的算法,方便集成于工程项目,被广泛应用于网络报文中的安全传输和认证.下面以md5,sha256,des,rsa几个典型的api简单使用作为例子. 算法介绍 ...

  3. MD5 不可逆加密,Des对称可逆加密 ,RSA非对称可逆加密 ,数字证书 SSL

    :MD5 不可逆加密2:Des对称可逆加密3:RSA非对称可逆加密4:数字证书 SSL Anker_张(博客园)http://www.cnblogs.com/AnkerZhang/ 1:MD5 不可逆 ...

  4. Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

    MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...

  5. 使用openssl库实现RSA、AES数据加密

         openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密.可以使用非对称加密:公钥加密,私钥解密.openssl提供了对RSA的支持,但RSA存在计算效率低的问题,所 ...

  6. Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完毕測试代码)

    MD5和RSA是网络传输中最经常使用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,仅仅能加密而不能解密. ...

  7. Android网络传输中必用的两个加密算法:MD5 和 RSA

    MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...

  8. openssl 非对称加密算法RSA命令详解

    1.非对称加密算法概述 非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下: 1.加密密钥和解密密钥不同 2.密钥对中的一个密钥可以公开 3.根据公开密钥很 ...

  9. [转]使用openssl库实现RSA、AES数据加密

    openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密.可以使用非对称加密:公钥加密,私钥解密.openssl提供了对RSA的支持,但RSA存在计算效率低的问题,所以一般的做 ...

随机推荐

  1. 如何使用g++编译调用dll的c++代码

    本文将有以下4个部分来讲如何使用g++编译调用dll的c++代码. 1.如何调用dll 2.动态链接和静态链接的区别 3.g++的编译参数以及如何编译调用dll的c++代码 4.总结 1.如何调用dl ...

  2. Math 类的使用(一小部分)

    package com.Date.Math; /* Math 数学类, 主要是提供了很多的数学公式. abs(double a) 获取绝对值 ceil(double a) 向上取整 floor(dou ...

  3. CMD命令去导出文件下的文件名称到EXCEL

      dir C:\Users\caire\Pictures\壁纸/b>E:\temp.xls

  4. mysql按日期分组统计数据

    最近在做一个招聘网时,需要显示一个月内企业招聘信息的发布数量,按日期分组统计,刚开始是直接从源数据库表里面进行group by,但这样子就出现日期不连续的问题了,我想要的效果是,若当天没有数据,则显示 ...

  5. SpringBoot(九)_springboot集成 MyBatis

    MyBatis 是一款标准的 ORM 框架,被广泛的应用于各企业开发中.具体细节这里就不在叙述,大家自行查找资料进行学习下. 加载依赖 <dependency> <groupId&g ...

  6. mysql 开发基础系列3

    日期类型 如果要用来表示年月日,通常用DATE 来表示. 如果要用来表示年月日时分秒,通常用DATETIME 表示. 如果只用来表示时分秒,通常用TIME 来表示. TIMESTAMP表示格式 :YY ...

  7. struts下载文件

  8. TypeError: to_categorical() got an unexpected keyword argument 'nb_classes'

    在学习莫烦教程中keras教程时,报错:TypeError: to_categorical() got an unexpected keyword argument 'nb_classes',代码如下 ...

  9. URAL 1969. Hong Kong Tram

    有一个trick就是没想到,枚举第二段时间后,要检测该火车能否继续跑一圈来判断,不能先检测前半圈能不能跑加进去后在检测后半段: // **** 部分不能放在那个位置: 最近代码导致的错误总是找不出,贴 ...

  10. JAVA ACM 基础

    java ACM Java做ACM-ICPC的特点: (1) 在一般比赛中,Java程序会有额外的时间和空间,而实际上经过实验,在执行计算密集任务的时候Java并不比C/C++慢多少,只是IO操作较慢 ...