OPENSSL库的使用-RSA篇

一、RSA算法简介

        RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
       RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
       RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
 
二、RSA算法加解密用到的函数
1、RSA基本结构
struct
     {
      int pad;
      long version;
      const RSA_METHOD *meth;
      ENGINE *engine;
      BIGNUM *n;         n=p*q
      BIGNUM *e;         公开的加密指数,经常为65537(ox10001)
      BIGNUM *d;         私钥
      BIGNUM *p;         大素数p
      BIGNUM *q;         大素数q
      BIGNUM *dmp1;      d mod (p-1)
      BIGNUM *dmq1;      d mod (q-1)
      BIGNUM *iqmp;      (inverse of q) mod p
      int references;
      int flags;
        // ...
      }RSA;


2、初始化函数
RSA * RSA_new(void);初始化一个RSA结构

3、RSA私钥产生函数
RSA *RSA_generate_key(int num, unsigned long e,void (*callback)(int,int,void *), void *cb_arg);产生一个模为num位的密钥对,e为公开的加密指数,一般为65537(0x10001),假如后两个参数不为NULL,将有些调用。在产生密钥对之前,一般需要指定随机数种子
 
4、判断位数函数
  int RSA_size(const RSA *rsa);返回RSA模的位数,他用来判断需要给加密值分配空间的大小
 
5、加解密函数
1)公钥加密函数
int RSA_public_encrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa, int padding);
 
2)私钥解密函数
int RSA_private_decrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa, int padding);
3)私钥加密函数
int RSA_private_encrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa,int padding);
4)公钥解密函数
int RSA_public_decrypt(int flen, unsigned char *from,unsigned char *to, RSA *rsa,int padding);
flen为要加/解密信息的长度,from为需要加/解密的信息,to为加/解密后的信息,一般to至少要申请 BN_num_bytes(rsa->n)大的空间。加密时Padding表示填充方式,解密时表示去填充方式。

6、 释放函数
void RSA_free(RSA *rsa);释放一个RSA结构
 
7、与字符串处理相关函数
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);将s中的len位的正整数转化为大数
 
三、代码示例
1、公钥加密
void CPage4::OnButtonPubDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();

 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);
 
 inputlen=RSA_size(pRsa);

 int ret = RSA_public_encrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("公钥加密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}


 
2、私钥解密
void CPage4::OnButtonPriDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 //inputlen=RSA_size(pRsa)-11;

 int ret = RSA_private_decrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("私钥解密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}


 
3、私钥加密
void CPage4::OnButtonEncrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 inputlen=RSA_size(pRsa);

 int ret = RSA_private_encrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("私钥加密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }
 
 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);

}


 

4、公钥解密
void CPage4::OnButtonDecrypt()
{
 // TODO: Add your control notification handler code here
 unsigned char rsaN[1024] = {0};
 unsigned char rsaD[1024] = {0};
 unsigned char rsaE[1024] = {0};
 unsigned char public_e[8] = {0};
 unsigned char publickey_n[1024] = {0};
 unsigned char privatekey_d[1024] = {0};
 unsigned char inputdata[1024] = {0};
 unsigned char output[1024] = {0};
 int e_len = 0;
 int n_len = 0;
 int d_len = 0;
 int inputlen = 0;

 UpdateData(TRUE);

 m_public_e.Remove(' ');
 m_publickey_n.Remove(' ');
 m_privatekey_d.Remove(' ');
 m_inputdata.Remove(' ');

 e_len = m_public_e.GetLength()/2;
    n_len = m_publickey_n.GetLength()/2;
 d_len = m_privatekey_d.GetLength()/2;
 inputlen = m_inputdata.GetLength()/2;

 StrToHex(m_public_e,public_e,e_len);
 StrToHex(m_publickey_n,publickey_n,n_len);
 StrToHex(m_privatekey_d,privatekey_d,d_len);
 StrToHex(m_inputdata,inputdata,inputlen);

 memcpy(rsaN,publickey_n,n_len);
 memcpy(rsaD,privatekey_d,d_len);
 memcpy(rsaE,public_e,e_len);

 RSA* pRsa = RSA_new();
 pRsa->n = BN_bin2bn(rsaN, n_len, NULL);
 pRsa->d = BN_bin2bn(rsaD, d_len, NULL);
 pRsa->e = BN_bin2bn(rsaE, e_len, NULL);

 //inputlen=RSA_size(pRsa)-11;

 int ret = RSA_public_decrypt(inputlen,inputdata,output, pRsa, RSA_NO_PADDING);
 if (ret < 0)
 {
  MessageBox("公钥解密失败,请检查输入数据是否正确!");
  RSA_free(pRsa);
  return;
 }

 RSA_free(pRsa);
 
 HexToStr(output,ret,m_outputdata);

 UpdateData(FALSE);
}


 
5、产生RSA密钥对
void CPage4::OnButtonRsa()
{
 // TODO: Add your control notification handler code here
 RSA* key;
 unsigned char rsa_n[1024];
 unsigned char rsa_d[1024];
 char keylen[10];
 int len;

 UpdateData(TRUE);

 strcpy(keylen,m_keylen);
 len = atoi(keylen);

 key = RSA_new();

 key = RSA_generate_key(len,0x10001,NULL,NULL);

 BN_bn2bin(key->n,rsa_n ); // 保存公钥
 BN_bn2bin(key->d,rsa_d ); // 保存私钥

 RSA_free(key);

 HexToStr(rsa_n,len/8,m_publickey_n);
 HexToStr(rsa_d,len/8,m_privatekey_d);

 UpdateData(FALSE);

}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值