1.加密后得内容中带有结束符,cout输出不能正常输出
2.将加密后的内容存到文件,解密的时候再读出来,可能会碰到结束符而提前终止读取文件,导致解密失败
3.将加密后的内容转为十六进制,解密再转回来是完全可以的,但是我将加密后的内容转为二进制会有问题,我看解密的时候具体数据都是一样的,却解密失败。这个我也未解决。

// OpenSSLDemo.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include<iostream>
#include <windows.h>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>
#include <sstream>
#include <io.h>
#include <direct.h>
#include "openssl/md5.h"
#include "openssl/sha.h"
#include "openssl/des.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include "base64.h"
#include "memery.h"
using namespace std;
#define KEY_LENGTH 2048
#define PUB_KEY_FILE "pubkey.pem"
#define PRI_KEY_FILE "prikey.pem"#pragma warning(disable:4996)void str_to_two(const UCHAR *str,int strLen,UCHAR *twoStr);
void two_to_str(const UCHAR *inData,int inDataLen,UCHAR *outStr);
string string_to_hex(std::string const &str);
string hex_to_string(std::string const &str);string getMsg(int ret)
{string message;switch (ret){case  0:message="失败"; break;case  1:message="成功"; break;default: message="未知错误";break;}return message;
}
//2进制转16进制
unsigned char char2HexChar(const unsigned char &x)
{return x>9?(x-10+'A'):x+'0';
}
//sha1加密
string sha1(const string &str)
{SHA_CTX c;SHA1_Init(&c);SHA1_Update(&c,str.c_str(),str.size());unsigned char szSha1[SHA_DIGEST_LENGTH]={0};SHA1_Final(szSha1,&c);string strSha1="";//  unsigned char strTmpHex;char buf[41] = {0};  char tmp[3] = {0}; for (int i=0;i<SHA_DIGEST_LENGTH;i++){/*strTmpHex=char2HexChar(szSha1[i]/16);strSha1.append(1,strTmpHex);strTmpHex=char2HexChar(szSha1[i]%16);strSha1.append(1,strTmpHex);*/sprintf_s(tmp,"%02x",szSha1[i]);strcat_s(buf,tmp);}//transform(strSha1.begin(), strSha1.end(), strSha1.begin(), ::tolower); return buf;}
string md5(const string &str)
{unsigned char md[16]={0};MD5_CTX md5;MD5_Init(&md5);MD5_Update(&md5,str.c_str(),str.size());MD5_Final(md,&md5);char buf[33]={0};char tmp[3]={0};for(int i=0;i<16;i++){sprintf_s(tmp,"%02x",md[i]);strcat_s(buf,tmp);}return buf;
}
//sha256加密
string sha256(const string &srcStr)//, std::string &encodedStr, std::string &encodedHexStr)
{  // 调用sha256哈希    unsigned char mdStr[SHA256_DIGEST_LENGTH] = {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};  string encodedStr;string encodedHexStr;for (int i = 0; i < 32; i++)  {  sprintf(tmp, "%02x", mdStr[i]);  strcat(buf, tmp);  }  //buf[32] = '\0'; // 后面都是0,从32字节截断    return buf;
}//des对称加密
/********************************************************
DES加密原理:DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位
(每组的第8位作为奇偶校验位),产生最大 64 位的分组大小。
这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将
加密的文本块分成两半。使用子密钥对其中一半应用循环功能,
然后将输出与另一半进行“异或”运算;接着交换这两半,
这一过程会继续下去,但最后一个循环不交换。DES 使用 16
轮循环,使用异或,置换,代换,移位操作四种基本运算。
**********************************************************/
// ecb模式
string des_encrypt(string &text,const string &key)
{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;vector<unsigned char> vecCiphertext;unsigned char tmp[8]={0};for (size_t i=0;i<text.length()/8;i++){memcpy(inputText,text.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(text.length()%8!=0){int tmp1=text.length()/8*8;int tmp2=text.length()-tmp1;memset(inputText,0,8);memcpy(inputText,text.c_str()+tmp1,tmp2);//加密函数DES_ecb_encrypt(&inputText,&outputText,&keySchedule,DES_ENCRYPT);memcpy(tmp,outputText,8);for (int i=0;i<8;i++){vecCiphertext.push_back(tmp[i]);}}cipherText.clear();cipherText.assign(vecCiphertext.begin(),vecCiphertext.end());return cipherText;
}//解密ecb
string des_decrypt(const string &cipherText,const string &key)
{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 keyScheule;DES_set_key_unchecked(&keyEncrypt,&keyScheule); //设置密码表,不校验const_DES_cblock inputText;DES_cblock outputText;vector<unsigned char> vecClearText;unsigned char tmp[8];for (size_t i=0;i<cipherText.length()/8;i++){memcpy(inputText,cipherText.c_str()+i*8,8);DES_ecb_encrypt(&inputText,&outputText,&keyScheule,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,&keyScheule,DES_DECRYPT);memcpy(tmp,outputText,8);for (int i=0;i<8;i++){vecClearText.push_back(tmp[i]);}}clearText.clear();clearText.assign(vecClearText.begin(),vecClearText.end());return clearText;
}
int writeFile(const char *fileName,const string data)
{string path="..//file//";if(access(path.c_str(),0)==-1) //-1为未创建{int i=mkdir(path.c_str());if (i){cout<<"创建目录失败"<<endl;return 0;}}FILE *f=NULL;path+=fileName; //文件的完整路径f=fopen(path.c_str(),"w");if(f==NULL){cout<<"打开文件失败!"<<endl;return 0;}if(fwrite(data.c_str(),data.size(),1,f)==EOF){cout<<"写入文件错误!"<<endl;return 0;}fclose(f);return 1;
}string readFile(const string  fileName)
{string data;string path="..//file//";path+=fileName; //完整路径FILE *f=NULL;f=fopen(path.c_str(),"rb");if(f==NULL){cout<<"读取文件失败!"<<endl;return 0;}//char *buf=new char[2048];unsigned char buf={0};int i=0;while (fread(&buf,sizeof(unsigned char),1,f))  //一直读 {//fgets(buf,2048,f);//cout<<buf;//data.append(( char*)buf);data+=buf;//memset(buf,0,strlen((char*)buf));}fclose(f);//delete [] buf;//buf=NULL;//cout<<data<<endl;//memcpy((char*)data.c_str(),tmp,i);return data;}
/***********************
*   rsa非对称加密     **
************************
*///生成密钥对
int generateRSAkey()
{string pubKey;string priKey;//公私密钥对size_t pri_len;size_t pub_len;char *pri_key=NULL;char *pub_key=NULL;//生成密钥对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=new char[pri_len+1];pub_key=new char[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';//存储秘钥对pubKey=pub_key;priKey=pri_key;//存储到磁盘(这种方式)writeFile(PUB_KEY_FILE,pub_key);writeFile(PRI_KEY_FILE,pri_key);//内存释放RSA_free(keypair);BIO_free_all(pub);BIO_free_all(pri);delete []pri_key;delete []pub_key;return 1;}
//公钥加密
int rsa_pub_encrypt(const string &clearText,const string &pubKey)
{string strRet;RSA *rsa=NULL;BIO *keybio=BIO_new_mem_buf((unsigned char*)pubKey.c_str(),-1);//三种方式//1.读取内存里生成的密钥对,再从内存生成rsa//2.读取磁盘里生成的密钥对文本文件,再从内存生成rsa//3.直接从读取文件指针生成rsaRSA *pRSAPublicKey=RSA_new();rsa=PEM_read_bio_RSAPublicKey(keybio,&rsa,NULL,NULL);int len=RSA_size(rsa);char *encryptedText=new char[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=string(encryptedText,ret);writeFile("rsa_en.txt",strRet);string strHex=string_to_hex(strRet); //将加密后的内容转为16进制writeFile("rsa_en_16.txt",strHex);unsigned char twoArray[5000]={0};str_to_two((unsigned char*)strRet.c_str(),strRet.size(),twoArray); //将加密后的内容转为2进制//memcpy((char*)strTwo.c_str(),twoArray,strlen((char*)twoArray));writeFile("rsa_en_2.txt",string((char*)twoArray));}//释放内存delete []encryptedText;BIO_free_all(keybio);RSA_free(rsa);return 1;}
//私钥解密
int rsa_pri_decrypt(const string cipherText,const string priKey)
{//将16进制字符转为原加密后的字符string en_data=hex_to_string(cipherText); //转换成原 加密后的内容writeFile("cipherText.txt",en_data);//以下生成的16进制字符 是为了 和    rsa加密后字符转为16进制字符串   进行比对的文件   string cipherText16=string_to_hex(en_data); writeFile("A_rsa_de_16.txt",cipherText16);//一下生成的2进制字符是  为了和之前加密后内容转换成的2进制字符进行比较unsigned char twoArray[5000]={0};str_to_two((unsigned char*)en_data.c_str(),en_data.size(),twoArray);writeFile("A_rsa_de_2.txt",string((char*)twoArray));string strRet;RSA *rsa=RSA_new();//string path="..//file//prikey.pem";/*FILE *f=fopen(path.c_str(),"rb+");rsa = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);if(rsa==NULL){printf("unable to read private key!\n");return NULL; } */BIO *keybio;keybio=BIO_new_mem_buf((unsigned char*)priKey.c_str(),-1);//三种方式//1.读取内存里生成的密钥对,再从内存生成rsa//2.读取磁盘里生成的密钥对文本文件,再从内存生成rsa//3.直接从读取文件指针生成rsarsa=PEM_read_bio_RSAPrivateKey(keybio,&rsa,NULL,NULL);// 从文件中读取私钥int len=RSA_size(rsa);char *decryptedText=new char[len+1];memset(decryptedText,0,len+1);int ret=RSA_private_decrypt(en_data.size(),(unsigned char*)en_data.c_str(),(unsigned char*)decryptedText,rsa,RSA_PKCS1_PADDING);if(ret>=0){strRet=string(decryptedText,ret);writeFile("rsa_de.txt",decryptedText);}elsereturn 0;//释放内存delete []decryptedText;BIO_free_all(keybio);RSA_free(rsa);return 1;}
/******************************************
** 功能:字符转二进制
** 参数:
**      str:输入的字符
**      strLen:输入字符串的长度
**      twoStr:字符串转换成的二进制
*******************************************
*/
void str_to_two(const UCHAR *str,int strLen,UCHAR *twoStr)
{UCHAR k=0x80;  //解密按位与运算 128 10000000for (int i = 0; i < strLen; i++,str++){k = 0x80;for (int j=1; j<=8; j++, k >>= 1){if (*str & k){*twoStr='1';twoStr++;}else{*twoStr='0';*twoStr++;}}}twoStr++;*twoStr='\0'; //结束字符串}/******************************************
** 功能:二进制转字符
** 参数:
**      inData:输入的二进制数组
**      inDataLen:输入二进制数组的长度
**      outStr:二进制转换后的字符
*******************************************
*/
void two_to_str(const UCHAR *inData,int inDataLen,UCHAR *outStr)
{char TwoStr[9]=""; //存放每个字符 8bitint kk=0; //记录字符串的数量for(int i=0;i<inDataLen;i=i+8){int l=0;strncpy(TwoStr,(const char*)inData+i,8);//把每一个字符的8bit 复制给outDatafor(int j=0;j<8;j++) {   l+=(TwoStr[j]-'0')<<(7-j); //转换成十进制outStr[kk]=l;}++kk;}outStr[kk]='\0';}string string_to_hex(string const &str)
{string ret;for (unsigned i = 0; i != str.size(); ++i){char hex[6]={0};sprintf(hex, "%#.2x ", (unsigned char)str[i]);ret += hex;}return ret;
}string hex_to_string(string const &str)
{string ret;istringstream iss(str);for (string buf; getline(iss, buf, ' ');){unsigned int value;sscanf(buf.c_str(), "%x", &value);ret += ((char)value);}return ret;
}int _tmain(int argc, _TCHAR* argv[])
{const  char* str="shenxuebing hello wordl!沈雪冰**--(1995.5.19)*)(&*%@‘;。《》";int ret=-1;cout<<"------------------------------MD5-----------------------------"<<endl;writeFile("MD5.txt",md5(str));cout<<md5(str)<<endl;cout<<"------------------------------SHA1-----------------------------"<<endl;writeFile("SHA1.txt",sha1(str));cout<<sha1(str)<<endl;cout<<"------------------------------SH256----------------------------"<<endl;writeFile("SHA256.txt",sha256(str));cout<<sha256(str)<<endl;cout<<"------------------------------DES_ECB加密----------------------------"<<endl;string desKey="123456";string enstr=des_encrypt(string(str),desKey);writeFile("DES_ECB_en.txt",enstr);//readFile("DES_ECB.txt");cout<<"------------------------------DES_ECB解密----------------------------"<<endl;string destr=des_decrypt(enstr,"123456");writeFile("DES_ECB_de.txt",destr);cout<<"------------------------------生成密钥对----------------------------";ret=generateRSAkey();cout<<getMsg(ret)<<endl;cout<<"------------------------------公钥加密----------------------------";string pubKey;pubKey=readFile("pubkey.pem");cout<<getMsg(rsa_pub_encrypt(str,pubKey))<<endl;cout<<"------------------------------私钥解密----------------------------";string priKey=readFile("prikey.pem");string rsa_en_16=readFile("rsa_en_16.txt");ret=rsa_pri_decrypt(rsa_en_16,priKey);cout<<getMsg(ret)<<endl;system("pause");return 0;
}

OpenSSL C++简单应用相关推荐

  1. Linux OPENSSL的简单用法

    使用OPENSSL可以加密用户数据 openssl paswd 可以加密用户的密码 -1代表使用MD5的加密方式 -salt指定随机数 虽然这个随机数是静态指定的. 生成随机数 输出内容中两个等号是b ...

  2. 基于openEuler的OpenSSL编译安装和编程基础

    文章目录 基于openEuler的OpenSSL编译安装和编程基础 OpenSSL编译安装 OpenSSL命令的使用 OpenSSL编程 简单测试 BASE64算法 作业 参考资料 基于openEul ...

  3. HTTPS通信的C++实现

    HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL.Nebula是一个为开发者提供一个快速开发高并 ...

  4. php composer 安装,composer安装的方法步骤(图文)

    composer的安装 注:我是的PHPstudy下安装的,其他情况也相似 一.配置环境变量 1.打开系统高级设置,具体操作如下图: 路径就是php根目录 2.打开openssl 注:phpstudy ...

  5. error: invalid application of 'sizeof' to an incomplete type 'JNINativeMethod []'

    android studio比较奇葩得把new char[100]{"fff"}这样的直接写成字面值常量 而window 的jni则必须使用这种 -- 尴尬 然后发现2个jni文件 ...

  6. OPENSSL-CA

    一.OpenSSL简单介绍 OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. SSL是Secur ...

  7. ACE 安装指南及示例

    The ADAPTIVE Communication Environment (ACE) 是一套免费的.开源的面向对象框架,它为大规模并发通信软件实现了许多核心的设计模式.ACE提供了一套丰富的.可重 ...

  8. vc8+ACE5.5 安装心得

    网上的一些文章对于ACE的安装很详细,但也很千篇一律.实践中你会遇到很多问题,但网上解决办法比较少.为此写了这篇文章,分享之. 由于VC6.0对c++标准支持的不好,所以编译ACE,虽然不会报错,但编 ...

  9. RTMP推流及协议学习

    前期准备 了解RTMP定义 准备RTMPDump中的librtmp 使用openssl中的libssllibcrypto 推流工作 整体框架图 使用libtrmp提供的API 将streaming封装 ...

最新文章

  1. 计算机网络协议教案,计算机网络实验教案(6)网络协议分析-IP协议3.pdf
  2. 如何用视觉的方法量身高?
  3. 49.检测对象是否为原始对象
  4. Android学习--持久化(三) SQLite LitePal
  5. Python之区块链入门,揭秘比特币
  6. linux设备和驱动注册,Linux驱动第五篇-----驱动注册和生成设备节点
  7. Linux Kernel Oops异常分析
  8. Linux CPU 信息查看
  9. 公司为什么宁愿花11K月薪招新人,也不愿意花9K的月薪留住老员工?
  10. snownlp文本分词、情感分析、文本相似度与摘要生成
  11. php算法求出一个数可以被分解成多少个_程序员的算法趣题
  12. 10G家庭光纤网络如何部署?
  13. 查看思科交换机出厂时间
  14. es拼音分词 大帅哥_elasticsearch实现中文分词和拼音分词混合查询+CompletionSuggestion...
  15. 视频如何做成gif动图?
  16. Nmap常用扫描命令
  17. 数据库的升序降序排列
  18. 漫步数理统计三十——依概率收敛
  19. vue 多页面应用搭建
  20. js判断身份证号码是否正确

热门文章

  1. 谷歌PR权重劫持的原理与方法介绍
  2. 卧槽!一行代码让 Python 的运行速度提高100倍
  3. 阿里云centos环境之Let's Encrypt SSL证书配置十一
  4. 技术驱动赋能医美 新氧奋力前行
  5. 某知名支付系统的架构演进权威分析
  6. matlab里BP神经网络实现实例2汽油辛烷值预测
  7. APP的图标测试之震惊!双11快到了,你的app在偷偷更换图标?
  8. 正则表达式匹配USD格式
  9. imx6ul linux读取DS18B20温度
  10. 【MicroPython】基于microbit的MicroPython编程--HELLO WORLD