OPENSSL库的使用-RSA篇
来源:互联网 发布:淘宝网童装套装 编辑:程序博客网 时间:2024/06/11 05:17
一、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结构
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、 释放函数
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);}
0 0
- OPENSSL库的使用-RSA篇
- OPENSSL库的使用-RSA篇
- OpenSSL库的RSA使用
- OpenSSL库的RSA使用(下)-rsa函数方式
- OpenSSL库的RSA使用(下)-rsa函数方式
- Openssl --RSA加密算法的使用
- Openssl --RSA加密算法的使用
- Openssl --RSA加密算法的使用。
- OpenSSL RSA的简单使用
- 使用Python的OpenSSL库来进行RSA加密
- 使用Python的OpenSSL库来进行RSA加密
- OpenSSL库的RSA使用(上)-EVP方式
- openssl中aes、rsa算法的使用
- Ubuntu16.04 使用OpenSSL库实现RSA
- openssl RSA命令使用
- openssl RSA DSA 加密算法使用
- RSA加密解密(直接使用openssl生成的公私钥)
- 使用openssl库实现RSA、AES数据加密
- html5多媒体标签之video标签
- mapreduce原理
- Android Studio生成keystore签名文件
- 洛谷 P1417 烹调方案
- TensorFlow--学习笔记
- OPENSSL库的使用-RSA篇
- 流程用例之OmniGraffle
- C# CRC16校验
- 属性动画
- git 项目管理之打标签tag
- 为什么在Service中创建子线程而不是Activity中
- unity延时方法Invoke和InvokeRepeating(方法技术记载)
- Android 柱状图
- VHD 多系统安装 无需分区 无需U盘 无需任何第三方工具