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 ;
}
浙公网安备 33010602011771号