非对称加密:即两端使用一对不同的密钥进行加密。

在非对称加密中,需要两对密钥,公钥和私钥。

公钥个私钥属于对立关系,一把加密后,只有另一把才可以进行解密。

  • 公钥数据加密

数字证书内包含了公钥,在进行会话连接时,双方交换各自的公钥,保留自己的私钥。进行数据传输时,利用对方的公钥进行数据加密。加密后的数据只有对方的私钥才能进行解密。

  • 私钥数字签名

私钥进行数据加密,所有人用公钥都能解密数据,但是加密后的数据却唯有私钥能生成。可以用于消息来源验证。将数据用私钥加密并明文告诉用户密文内容,用户进行公钥解密比较确认数据来源可靠。

在非对称加密算法中有RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。

其中RSA加密最为广泛利用,毫不夸张地说,只要有计算机网络的地方,就有RSA算法。

其原理为数论中一个公认的定论:两个大素数相乘非常容易,但是这个数要分解成二个质数的积,非常困难。

根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

具体RSA加密算法在计算机网络中的运用方式和原理可以查看:OpenSSL - 网络安全之数据加密和数字证书

如何利用openssl命令行来生成证书和密钥可查看:OpenSSL - 利用OpenSSL自签证书和CA颁发证书

在使用OpenSSL进行RSA加密算法时,流程与上述理论流程保持一致。

  • 生成密钥或读取密钥
  • 根据需要选择签名还是加密
  • 使用公钥进行数据加密
  • 使用私钥进行数字签名
  • 数据通过网络进行安全传输
  • 对端进行解密获取明文

下面是OpenSSL的RSA加密算法对数据进行加密解密过程实现:

 #include <iostream>
 #include <fstream>
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
 #include <openssl/pem.h>

 #define DATA_BUFF_LENTH 1024
 #define RSA_BIT 1024

 using namespace std;

 class File
 {
 public:
     File(string strFilePath):m_strFilePath(strFilePath){};
     ~File(){};
     bool open(_Ios_Openmode opreator);
     void close();
     void read(char* buff,int length);
 private:
     fstream m_file;
     string m_strFilePath;
 };

 bool File::open(_Ios_Openmode opreator)
 {
     m_file.open(m_strFilePath.c_str(),opreator);
     if (m_file.fail())   //打开失败
     {
         cout<<"open file failure!"<<endl;
         return false;
     }
     return true;
 }

 void File::close()
 {
     m_file.close();
 }

 void File::read(char* buff,int length)
 {
     m_file.read(buff,length);
 }

 class RSAKey
 {
 public:
     RSAKey(int rsabit,int bignum);
     ~RSAKey();
     void UsePrivateRSAKeyDecode(char* dsc,char* src);   //加密解密操作
     void UsePublicRSAKeyEncode(char* dsc,char* src);
     void printPublicKey();  //打印秘钥操作
     void printPrivateKey();
     void exportPrivateKey(string fileName); //导出秘钥操作
     void exportPublicKey(string fileName);
     /*
     We can also output the key into an encrypted PEM file.

     And the APIs is easy to use.

     PEM_write_bio_RSAPrivateKey

     PEM_write_bio_RSAPublicKey

     PEM_read_bio_RSAPrivateKey

     PEM_read_bio_RSAPublicKey
     */
     void importPrivateKey(string fileName); //导入秘钥操作,也可利用上述API通过证书导入秘钥,证书命令行生成和颁发签证
     void importPublicKey(string fileName);
 private:
     BIGNUM* m_bigNum;
     RSA* m_rsa;
     int m_rsa_bit;
     RSA* m_pubKey;
     RSA* m_privateKey;
 };

 RSAKey::RSAKey(int rsabit,int bignum)
 {
     m_rsa_bit = rsabit;
     m_rsa = RSA_new();
     m_pubKey = RSA_new();
     m_privateKey = RSA_new();
     m_bigNum = BN_new();
     BN_set_word(m_bigNum,bignum);   //设置大数
     RSA_generate_key_ex(m_rsa,m_rsa_bit,m_bigNum,NULL); //生成密钥
 }

 RSAKey::~RSAKey()
 {
     RSA_free(m_rsa);
     RSA_free(m_pubKey);
     RSA_free(m_privateKey);
     BN_free(m_bigNum);
 }

 void RSAKey::UsePrivateRSAKeyDecode(char* dsc,char* src)
 {
     int rsa_len = RSA_size(m_privateKey);
     RSA_private_decrypt(rsa_len,(unsigned char *)src,(unsigned char*)dsc,m_privateKey,RSA_NO_PADDING);
 }

 void RSAKey::UsePublicRSAKeyEncode(char* dsc,char* src)
 {
     int rsa_len = RSA_size(m_pubKey);
     RSA_public_encrypt(rsa_len, (unsigned char *)src,(unsigned char*)dsc,m_pubKey, RSA_NO_PADDING);
 }

 void RSAKey::printPublicKey()
 {
     RSA_print_fp(stdout,m_pubKey,);
 }

 void RSAKey::printPrivateKey()
 {
     RSA_print_fp(stdout,m_privateKey,);
 }

 void RSAKey::exportPrivateKey(string fileName)
 {
     FILE *ifile;
     ifile = fopen(fileName.c_str(),"w");
     PEM_write_RSAPrivateKey(ifile,m_rsa, NULL, NULL, , NULL, NULL);
     fclose(ifile);
 }

 void RSAKey::exportPublicKey(string fileName)
 {
     FILE *ifile;
     ifile = fopen(fileName.c_str(),"w");
     PEM_write_RSAPublicKey(ifile,m_rsa);
     fclose(ifile);
 }

 void RSAKey::importPrivateKey(string fileName)
 {
     FILE *ifile;
     ifile = fopen(fileName.c_str(),"r");
     m_privateKey = PEM_read_RSAPrivateKey(ifile, NULL, NULL, NULL);
 }

 void RSAKey::importPublicKey(string fileName)
 {
     FILE *ifile;
     ifile = fopen(fileName.c_str(),"r");
     m_pubKey = PEM_read_RSAPublicKey(ifile,NULL,NULL,NULL);
 }

 int main(int arc,char *arv[])
 {
     RSAKey rsa(RSA_BIT,RSA_F4);
     rsa.exportPrivateKey("private.key");    // 导出密钥
     rsa.exportPublicKey("public.key");

     ];
     File ifile(strFilePath.c_str());
     ifile.open(ios::in);

     char DataBuff[DATA_BUFF_LENTH];
     ifile.read(DataBuff,DATA_BUFF_LENTH);   //读文件内容
     ifile.close();

     rsa.importPublicKey("public.key");  //导入公钥
     rsa.importPrivateKey("private.key");    //导入秘钥

     rsa.printPrivateKey();  //打印秘钥信息
     rsa.printPublicKey();   //打印公钥信息

     cout<<"-----------------------------------"<<endl;
     cout<<"source :"<<DataBuff<<endl;   //源数据
     cout<<"-----------------------------------"<<endl;

     char enData[DATA_BUFF_LENTH];
     rsa.UsePublicRSAKeyEncode(enData,DataBuff);
     cout<<"-----------------------------------"<<endl;
     cout<<"encode :"<<enData<<endl;     //加密数据
     cout<<"-----------------------------------"<<endl;

     char deData[DATA_BUFF_LENTH];
     rsa.UsePrivateRSAKeyDecode(deData,enData);
     cout<<"-----------------------------------"<<endl;
     cout<<"decode :"<<deData<<endl;     //解密数据
     cout<<"-----------------------------------"<<endl;

     ;
 }

scons编译脚本如下:

 Program('pubkey','rsa_genkey.cpp',LIBS = ['ssl','crypto'])

执行可执行文件,输入文件路径,即可查看到经过RSA加密后的数据内容和解密后的内容。

从证书中提取公钥加密与上述代码类似,替换相应API即可。

tips:本来把这篇OpenSSL的RSA加密算法和代码写好点的,但是由于最近时间越来越紧张。后续有机会在扩充吧。代码部分很多地方没有做异常判段和处理,只是保证了正常功能。

由于后面参与公司新的后台服务器架构开发,将会使用到RabbitMQ中间件,后续将不定期慢速更新RabbitMQ及后台架构设计相关博客,欢迎关注!

OpenSSL - RSA非对称加密实现的更多相关文章

  1. CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互

    (以下代码中都只做测试用,有些地方没有释放内存...这个自己解决下) 1.RSA非对称的,首先提供一个供测试用的证书和私钥的数据 1)pem格式的证书和私钥(公私钥是对应的)的base64编码 voi ...

  2. 支付宝开发(一)-认识php openssl RSA 非对称加密实现

    获取支付宝公钥 本地服务器生成私钥和公钥 运用php中openssl相关函数加密解密验证身份 以下是php中openssl相关函数实现的验证,来自php官方demo //需要签名的数据 $data = ...

  3. RSA非对称加密 php的openssl实现

    <?php /** * 使用openssl实现非对称加密 * @since 2010-07-08 */ class Rsa { /** * private key */ private $_pr ...

  4. RSA 非对称加密,私钥转码为pkcs8 错误总结

    RSA 非对称加密,私钥转码为pkcs8 错误总结 最近在和某上市公司对接金融方面的业务时,关于RSA对接过程中遇到了一个坑,特来分享下解决方案. 该上市公司简称为A公司,我们简称为B公司.A-B两家 ...

  5. Atitit RSA非对称加密原理与解决方案

    Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制  3 1.4. 基于rsa的授权验证机器码 4 1.5. ...

  6. RSA非对称加密Java实现

    原文 加密基础方法类 import java.security.MessageDigest; import sun.misc.BASE64Decoder; import sun.misc.BASE64 ...

  7. 前端js,后台python实现RSA非对称加密

    先熟悉使用 在后台使用RSA实现秘钥生产,加密,解密; # -*- encoding:utf-8 -*- import base64 from Crypto import Random from Cr ...

  8. 前后端数据加密传输 RSA非对称加密

    任务需求:要求登陆时将密码加密之后再进行传输到后端. 经过半天查询摸索折腾,于是有了如下成果: 加密方式:RSA非对称加密.实现方式:公钥加密,私钥解密.研究进度:javascript与java端皆已 ...

  9. php RSA非对称加密 的实现

    基本概念 加密的意义 加密的意义在于数据的传输过程中,即使被第三方获取到传输的数据,第三方也不能获取到数据的具体含义. 加密方式分为对称加密和非对称加密 什么是对称加密? 对称加密只使用一个秘钥,加密 ...

随机推荐

  1. IOS开发基础知识--碎片13

    1:运行程序报the file couldn't be opened because you don't have permission to view it 解决办法:项目—>targets- ...

  2. C#socket通信-----多线程

    我在之前的socket通信的基础上做了一点改进,使用多线程来使用,程序更加简洁实用.不足之处请指教哦! 话不多说,之前的随笔也有介绍,直接上代码啦! 服务端socket(serverSocket): ...

  3. 6款好用的Python IDE

    “工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员吃饭的家伙了.一个优秀的IDE,最重要的就是在普通文本编辑之外,提供针对特定语言的各种快捷编辑功能,让程序员尽可能快捷.舒适. ...

  4. Wireshark &quot;The NPF driver isn’t running…&quot;(可见的驱动本质上是一个系统服务,使用net start 启动)

    前几天重装系统,装上了windows7 RC系统.昨天开始尝试装上了wireshark 这款很强大的网络监视软件,满心欢喜的打开,可是每次打开都会弹出“The NPF driver isn't run ...

  5. xcode忽略警告

    1.对整个文件使用 你的工程 -> 你的target -> Build Phases -> Compile Sources -> 搜索要忽略警告的文件名,在 Compiler ...

  6. JavaScript中的文档模式和严格模式

    JavaScript中的文档模式和严格模式 语法模式有普通模式和严格模式两种 普通模式:正常的JavaScript语法拼写以及代码编写(相对于严格模式存在着语法上的不严谨),尽可能的识别错误以及不规范 ...

  7. MySQL意外关闭, 导致软件崩溃而无法启动的解决办法

    在初次搭建XAMPP,Apache和MySQL都可以正常启动,一旦关机重启XAMPP时,发现Apache可以正常启动:而MySQL却不能正常运行,会碰到 Error: MySQL shutdown u ...

  8. 一些常用的CSS样式

    1. overflow: auto 允许盒子容器内容自动上下滚动 2. style="color:red solid" 设置元素边框样式 3.  white-space:nowra ...

  9. Linux System Programming --Chapter Eight

    内存管理 一.分配动态内存的几个函数 用户空间内存分配:malloc.calloc.realloc1.malloc原型如下:extern void *malloc(unsigned int num_b ...

  10. Map 转换成byte[] 数组

    把Map转换成byte数组,使用 ByteArrayOutputStream和ObjectOutputStream Map<String,String> map = new HashMap ...