zoukankan      html  css  js  c++  java
  • OpenSSL

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

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

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

    • 公钥数据加密

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

    • 私钥数字签名

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

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

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

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

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

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

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

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

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

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

      1 #include <iostream>
      2 #include <fstream>
      3 #include <openssl/bn.h>
      4 #include <openssl/rsa.h>
      5 #include <openssl/pem.h>
      6 
      7 #define DATA_BUFF_LENTH 1024
      8 #define RSA_BIT 1024
      9 
     10 using namespace std;
     11 
     12 class File
     13 {
     14 public:
     15     File(string strFilePath):m_strFilePath(strFilePath){};
     16     ~File(){};
     17     bool open(_Ios_Openmode opreator);
     18     void close();
     19     void read(char* buff,int length);
     20 private:
     21     fstream m_file;
     22     string m_strFilePath;
     23 };
     24 
     25 bool File::open(_Ios_Openmode opreator)
     26 {
     27     m_file.open(m_strFilePath.c_str(),opreator);
     28     if (m_file.fail())   //打开失败
     29     {
     30         cout<<"open file failure!"<<endl;
     31         return false;    
     32     } 
     33     return true;
     34 }
     35 
     36 void File::close()
     37 {
     38     m_file.close();
     39 }
     40 
     41 void File::read(char* buff,int length)
     42 {
     43     m_file.read(buff,length);
     44 }
     45 
     46 class RSAKey
     47 {
     48 public:
     49     RSAKey(int rsabit,int bignum);
     50     ~RSAKey();
     51     void UsePrivateRSAKeyDecode(char* dsc,char* src);   //加密解密操作
     52     void UsePublicRSAKeyEncode(char* dsc,char* src);
     53     void printPublicKey();  //打印秘钥操作
     54     void printPrivateKey();
     55     void exportPrivateKey(string fileName); //导出秘钥操作
     56     void exportPublicKey(string fileName);
     57     /*
     58     We can also output the key into an encrypted PEM file.
     59 
     60     And the APIs is easy to use.
     61 
     62     PEM_write_bio_RSAPrivateKey
     63 
     64     PEM_write_bio_RSAPublicKey
     65 
     66     PEM_read_bio_RSAPrivateKey
     67 
     68     PEM_read_bio_RSAPublicKey
     69     */
     70     void importPrivateKey(string fileName); //导入秘钥操作,也可利用上述API通过证书导入秘钥,证书命令行生成和颁发签证
     71     void importPublicKey(string fileName);
     72 private:
     73     BIGNUM* m_bigNum;
     74     RSA* m_rsa;
     75     int m_rsa_bit;
     76     RSA* m_pubKey;
     77     RSA* m_privateKey;
     78 };
     79 
     80 RSAKey::RSAKey(int rsabit,int bignum)
     81 {
     82     m_rsa_bit = rsabit;
     83     m_rsa = RSA_new();
     84     m_pubKey = RSA_new();
     85     m_privateKey = RSA_new();
     86     m_bigNum = BN_new();
     87     BN_set_word(m_bigNum,bignum);   //设置大数
     88     RSA_generate_key_ex(m_rsa,m_rsa_bit,m_bigNum,NULL); //生成密钥
     89 }
     90 
     91 RSAKey::~RSAKey()
     92 {
     93     RSA_free(m_rsa);
     94     RSA_free(m_pubKey);
     95     RSA_free(m_privateKey);
     96     BN_free(m_bigNum);    
     97 }
     98 
     99 void RSAKey::UsePrivateRSAKeyDecode(char* dsc,char* src)
    100 {
    101     int rsa_len = RSA_size(m_privateKey);
    102     RSA_private_decrypt(rsa_len,(unsigned char *)src,(unsigned char*)dsc,m_privateKey,RSA_NO_PADDING);
    103 }
    104 
    105 void RSAKey::UsePublicRSAKeyEncode(char* dsc,char* src)
    106 {
    107     int rsa_len = RSA_size(m_pubKey);
    108     RSA_public_encrypt(rsa_len, (unsigned char *)src,(unsigned char*)dsc,m_pubKey, RSA_NO_PADDING);
    109 }
    110 
    111 void RSAKey::printPublicKey()
    112 {
    113     RSA_print_fp(stdout,m_pubKey,11);
    114 }
    115 
    116 void RSAKey::printPrivateKey()
    117 {
    118     RSA_print_fp(stdout,m_privateKey,11);
    119 }
    120 
    121 void RSAKey::exportPrivateKey(string fileName)
    122 {
    123     FILE *ifile;
    124     ifile = fopen(fileName.c_str(),"w");
    125     PEM_write_RSAPrivateKey(ifile,m_rsa, NULL, NULL, 0, NULL, NULL);
    126     fclose(ifile);
    127 }
    128 
    129 void RSAKey::exportPublicKey(string fileName)
    130 {
    131     FILE *ifile;
    132     ifile = fopen(fileName.c_str(),"w");
    133     PEM_write_RSAPublicKey(ifile,m_rsa);
    134     fclose(ifile);
    135 }
    136 
    137 void RSAKey::importPrivateKey(string fileName)
    138 {
    139     FILE *ifile;
    140     ifile = fopen(fileName.c_str(),"r");
    141     m_privateKey = PEM_read_RSAPrivateKey(ifile, NULL, NULL, NULL);
    142 }
    143 
    144 void RSAKey::importPublicKey(string fileName)
    145 {
    146     FILE *ifile;
    147     ifile = fopen(fileName.c_str(),"r");
    148     m_pubKey = PEM_read_RSAPublicKey(ifile,NULL,NULL,NULL);
    149 }
    150 
    151 int main(int arc,char *arv[])
    152 {
    153     RSAKey rsa(RSA_BIT,RSA_F4);
    154     rsa.exportPrivateKey("private.key");    // 导出密钥
    155     rsa.exportPublicKey("public.key");
    156 
    157     string strFilePath = arv[1];
    158     File ifile(strFilePath.c_str());
    159     ifile.open(ios::in);
    160 
    161     char DataBuff[DATA_BUFF_LENTH];
    162     ifile.read(DataBuff,DATA_BUFF_LENTH);   //读文件内容
    163     ifile.close();
    164 
    165     rsa.importPublicKey("public.key");  //导入公钥
    166     rsa.importPrivateKey("private.key");    //导入秘钥
    167     
    168     rsa.printPrivateKey();  //打印秘钥信息
    169     rsa.printPublicKey();   //打印公钥信息
    170 
    171     cout<<"-----------------------------------"<<endl;
    172     cout<<"source :"<<DataBuff<<endl;   //源数据
    173     cout<<"-----------------------------------"<<endl;
    174     
    175     char enData[DATA_BUFF_LENTH];
    176     rsa.UsePublicRSAKeyEncode(enData,DataBuff);
    177     cout<<"-----------------------------------"<<endl;
    178     cout<<"encode :"<<enData<<endl;     //加密数据
    179     cout<<"-----------------------------------"<<endl;
    180     
    181     char deData[DATA_BUFF_LENTH];
    182     rsa.UsePrivateRSAKeyDecode(deData,enData);
    183     cout<<"-----------------------------------"<<endl;
    184     cout<<"decode :"<<deData<<endl;     //解密数据
    185     cout<<"-----------------------------------"<<endl;
    186 
    187     return 0;
    188 }
    View Code

    scons编译脚本如下:

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

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

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

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

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

  • 相关阅读:
    Java核心技术-映射
    Java核心技术-具体的集合
    Java核心技术-继承
    Spring MVC 起步
    最小化Spring XML配置
    装配Bean
    Bean和Spirng模块
    Spring入门
    git学习笔记
    CISCN2018-WP
  • 原文地址:https://www.cnblogs.com/binchen-china/p/5661573.html
Copyright © 2011-2022 走看看