openssl&linux下编程实现生成公私钥&非对称加密

2. 非对称加密

RSA 算法密钥长度越长,安全性越好,加密解密所需时间越长。

密钥长度增长一倍,公钥操作所需时间增加约 4 倍,私钥操作所需时间增加约 8 倍,公私钥生成时间约增长 16 倍;

  • 特点
    • 秘钥是一个密钥对: 公钥, 私钥
      • 公钥加密, 必须私钥解密
      • 私钥加密, 必须公钥解密
    • 加密强度比较高, 效率低
      • 不会使用非对称加密, 加密特别大的数据
  • 应用场景:
    • 秘钥分发 -> 对称加密
      • 核心思想: 加密的时候, 公钥加密, 私钥解密
      • 分发步骤:
        • 假设A, B两端
        • A端生成了一个密钥对, 分发公钥, B端有了公钥
        • B端生成一个对称加密的秘钥, 使用公钥加密 -> 密文
        • B将密文发送给A
        • A接收数据 -> 密文, 使用私钥对密文解密 -> 对称加密的秘钥
    • 签名 -> 验证数据是否被篡改, 验证数据的所有者
      • 核心思想: 私钥加密, 公钥解密
      • A, B两端, 假设A要发送数据
        • A端生成一个密钥对, 将公钥进行分发, 自己留私钥
      • 签名
        • A对原始数据进行哈希运算 -> 哈希值
        • A使用私钥对哈希值加密 -> 密文
        • 将原始数据+密文发送给B
      • 校验签名
        • B接收数据: 密文 + 收到的原始数据
        • 使用公钥对密文解密 -> 哈希值old
        • 使用has算法对收到的数据进行哈希运算 -> 哈希值new
        • 比较这两个哈希值
          • 相同: 校验成功
          • 不同: 失败

g++ demo.cpp -lcrypto -lssl

#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

int main ( int argc , char *argv[] )
{
   return 0 ;
}

如果没有任何提示信息输出的话, 说明 ssl 这个动态链接库已经可以正常工作了

makefile
srcFile=$(wildcard *.cpp)
srcHead=$(wildcard *.h)
#dstFile=$(patsubst %.cpp,%,$(srcFile))

LIBS=-lcrypto \
     -lssl \
     -ldl
INCLUDE=-I /usr/local/include/openssl \

APP=app

$(APP):
#   g++ -g -w -o$(APP) $(srcFile) $(srcHead) $(LIBS) $(srcHead)
    g++ -g -w -o$(APP) $(srcFile) $(srcHead) -lcrypto $(srcHead)                                      

#all:$(dstFile)

#%:%.cpp
#   g++ -o $@ $< -g $(INCLUDE) $(LIBS)

clean:
    -@rm -f $(dstFile)

Rsa_pair.h

#pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bn.h> 

class rsaPair
{
  public :
        rsaPair ()
        {
           pub_key = NULL ;
           pri_key = NULL ;
    }
    rsaPair ( std::string pub_k_path , std::string pri_key_path, std::string psword ) ;
    ~rsaPair () ;
    
    int create_key_pair () ;

  private :
    std::string pub_key_path ;
    std::string pri_key_path ;
    std::string password ;
    RSA *pub_key ;
    RSA *pri_key ;
} ;

rsa_pair.cpp

#include <stdio.h>

#include "rsa_pair.h"

using namespace std ;

rsaPair::rsaPair( string pub_k_path , string pri_k_path , string psword)
{
   pub_key = NULL ;
   pri_key = NULL ;


   if ( pub_k_path.empty () || pri_k_path.empty() )
   {
    perror ("file stores key values empty") ;
        return ;
   }
   
   if ( psword.empty ())
   {
    perror ("password empty , use default") ;
    password = "inuyasha" ;
      return ;
  }

   printf ("here ") ;
  
   pub_key_path = pub_k_path ;
   pri_key_path = pri_k_path ;
    
   password = psword ;

}

rsaPair::~rsaPair ()
{
    if ( pub_key )
       RSA_free ( pub_key ) ;
  
    if ( pri_key )
    RSA_free ( pri_key ) ;
}


int rsaPair::create_key_pair ()
{
  RSA *rsa ;
  int modulelen = 1024 ;
  int ret ;
  unsigned int len ;
  unsigned long e = RSA_3 ;
 
  BIGNUM *bn ;
  
  bn = BN_new () ;
  ret = BN_set_word ( bn , e ) ;
   
  if ( ret != 1 )
  {
    perror ("BN_set_word method goes wrong ") ;
    return -1 ;
  }
  
  rsa = RSA_new () ;

  if ( RSA_generate_key_ex ( rsa , modulelen , bn , NULL ) != 1 )
  {
    perror ("RSA_generate_key_ex method goes wrong") ;
    return -1 ;
  }

//---------------------------------------------------------------
  
  // public key
  BIO *bioPtr = BIO_new ( BIO_s_file () ) ;
  
  //----- open public key store file ------
  if ( BIO_write_filename ( bioPtr , (void*)pub_key_path.c_str ()) <= 0 )
  {
    perror ("failed to open public key file ") ;
    return -1 ;
  }
    
  //----- write public key into file -----
 
  if ( PEM_write_bio_RSAPublicKey( bioPtr , rsa ) != 1 )
  {
     perror ("failed to write RSA public key into file") ;
    return -1 ;
  }

  //----- if we get here , everything goes well -----
  printf ("generated RSA public key already written into file %s \n" , pub_key_path.c_str()) ;
  
  BIO_free_all( bioPtr ) ; // don't forget release and free the allocated space


//-----------------------------------------------------------------------------------------
   //----- private key -----
    
   bioPtr = BIO_new_file ( pri_key_path.c_str() , "w+") ;
   
   if ( bioPtr == NULL )
   {
    perror ("failed to open file stores RSA private key ") ;
       return -1 ;
   }

   if ( PEM_write_bio_RSAPrivateKey ( bioPtr , rsa ,EVP_des_ede3_ofb() ,
            (unsigned char *)password.c_str() , password.size() , NULL , NULL ) != 1 )
   {
    perror ("failed write RSA private key into file") ;
    return -1 ;
   }
    
   BIO_free_all ( bioPtr ) ; // do not forget this
   
   printf ("genertated RSA private key already written into file %s \n" , pri_key_path.c_str () ) ;

  return 0 ;
}

main.cpp

#include <cstdio>
#include <cstring>
#include <iostream>

#include "rsa_pair.h"

using namespace std ;

int main ( int argc , char **argv )
{

  string pub_key_path , pri_key_path ;
  string password ;
  
  cout << "public key path " << endl;
  cin >> pub_key_path ;
  cout << pub_key_path << endl ;


  cout << "private key path " << endl ;
  cin >> pri_key_path ;
  cout << pri_key_path <<endl ;
  

  cout << "password " << endl ;
  cin >> password ;
  cout << password <<endl;

  
 // rsaPair key_pair ;
  rsaPair key_pair ( pub_key_path , pri_key_path , password) ;
  
   key_pair.create_key_pair () ;
  
  
  return 0 ;
}

posted on 2021-05-30 23:52  lodger47  阅读(329)  评论(0)    收藏  举报

导航