如何利用OpenSSL库进行RSA加密和解密
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用OpenSSL库进行RSA加密和解密相关的知识,希望对你有一定的参考价值。
参考技术A #include<stdio.h>#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/engine.h>
int main(int argc, char* argv[])
printf("openssl_test begin\\n");
RSA* rsa=NULL;
char originstr[]="hello\\n"; //这是我们需要加密的原始数据
//allocate RSA structure,首先需要申请一个RSA结构题用于存放生成的公私钥,这里rsa就是这个结构体的指针
rsa = RSA_new();
if(rsa==NULL)
printf("RSA_new failed\\n");
return -1;
//generate RSA keys
BIGNUM* exponent;
exponent = BN_new(); //生成RSA公私钥之前需要选择一个奇数(odd number)来用于生成公私钥
if(exponent ==NULL)
printf("BN_new failed\\n");
goto FAIL1;
if(0==BN_set_word(exponent,65537)) //这里选择奇数65537
printf("BN_set_word failed\\n");
goto FAIL1;
//这里modulus的长度选择4096,小于1024的modulus长度都是不安全的,容易被破解
if(0==RSA_generate_key_ex(rsa,4096,exponent,NULL))
printf("RSA_generate_key_ex failed\\n");
goto FAIL;
char* cipherstr = NULL;
//分配一段空间用于存储加密后的数据,这个空间的大小由RSA_size函数根据rsa算出
cipherstr = malloc(RSA_size(rsa));
if(cipherstr==NULL)
printf("malloc cipherstr buf failed\\n");
goto FAIL1;
//下面是实际的加密过程,最后一个参数padding type,有以下几种。
/*
RSA_PKCS1_PADDINGPKCS #1 v1.5 padding. This currently is the most widely used mode.
RSA_PKCS1_OAEP_PADDING
EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty encoding parameter. This mode is recommended for all new applications.
RSA_SSLV23_PADDING
PKCS #1 v1.5 padding with an SSL-specific modification that denotes that the server is SSL3 capable.
RSA_NO_PADDING
Raw RSA encryption. This mode should only be used to implement cryptographically sound padding modes in the application code. Encrypting user data directly with RSA is insecure.
*/
//这里首先用公钥进行加密,选择了RSA_PKCS1_PADDING
if(RSA_size(rsa)!=RSA_public_encrypt(strlen(originstr)+1,originstr,cipherstr,rsa,RSA_PKCS1_PADDING))
printf("encryption failure\\n");
goto FAIL2;
printf("the original string is %s\\n",originstr);
printf("the encrypted string is %s\\n",cipherstr);
//Now, let's decrypt the string with private key
//下面来用私钥解密,首先需要一个buffer用于存储解密后的数据,这个buffer的长度要足够(小于RSA_size(rsa))
//这里分配一个长度为250的字符数组,应该是够用的。
char decrypted_str[250];
int decrypted_len;
if(-1=(decrypted_len=RSA_private_decrypt(256,cipherstr,decrypted_str,rsa,RSA_PKCS1_PADDING)))
printf("decryption failure\\n");
goto FAIL2;
printf("decrypted string length is %d,decryped_str is %s\\n",decrypted_len,decrypted_str);
FAIL2:
free(cipherstr);
FAIL1:
BN_free(exponent);
FAIL:
RSA_free(rsa);
return 0;
以上是源代码,下面使用下面的编译命令在源码所在路径下生成可执行文件
gcc *.c -o openssl_test -lcrypto -ldl -L/usr/local/ssl/lib -I/usr/local/ssl/include
其中,-lcrypto和-ldl是必须的,前者是OpenSSL中的加密算法库,后者是用于成功加载动态库。
OpenSSL PHP RSA 加密:在客户端使用哪个库解密?
【中文标题】OpenSSL PHP RSA 加密:在客户端使用哪个库解密?【英文标题】:OpenSSL PHP RSA Encryption: Which library to use to decrypt on client side? 【发布时间】:2012-02-06 04:05:17 【问题描述】:我开发了一个桌面应用程序 (.NET 2.0),它需要从运行 php/mysql 的服务器获取一些信息。服务器端的提供商决定使用 openssl_private_encrypt 方法进行加密,并为我提供了一个 publickey.pem 文件。我不擅长 php/mysql,但我知道如果我使用 asp .net 不会有任何不同。
我的问题是如何解密 .NET 2.0 应用程序中的私有加密数据。我所有使用带有公钥的 RSACrypoServiceProvider 的尝试都被证明是不成功的。
我偶然发现了 ManagedOpenSSL 库,但这也不好。
我确信 *** 的许多人都会做类似的事情,如果知道他们是如何做到的,那就太好了。
提前感谢您的所有帮助。
【问题讨论】:
【参考方案1】:.NET 使用 OpenSSL 不支持的 XML 格式的密钥。我的建议是使用phpseclib, a pure PHP RSA implementation 生成密钥对 - 或至少将现有密钥对转换为 XML。
【讨论】:
谢谢纽伯特。但是,生成密钥对意味着我要求服务器管理员使用我生成的私钥,我认为他们不会接受这样的请求。我将在下面发布答案。但是,我认为经过几个小时的打击和试验后,我设法让它工作了。我使用了 BouncyCastle,然后进行了一些尝试,设法弄明白了。【参考方案2】:这是我用来让它工作的!
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
string responseFromServerEnc = string.Empty;
byte[] data = null;
if (HttpStatusCode.OK == response.StatusCode)
MemoryStream memoryStream = new MemoryStream(0x10000);
using (Stream responseStream = request.GetResponse().GetResponseStream())
byte[] buffer = new byte[0x1000];
int bytes;
while ((bytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
memoryStream.Write(buffer, 0, bytes);
data = memoryStream.ToArray();
response.Close();
const string pubKey = "-----BEGIN PUBLIC KEY-----\n key from .pem file \n-----END PUBLIC KEY-----";
PemReader pem = new PemReader(new StringReader(pubKey));
RsaKeyParameters bcp = (RsaKeyParameters)pem.ReadObject();
string responseFromServer = Encoding.UTF8.GetString(Decrypt(data,bcp));
responseFromServerEnc 是加密消息,responseFromServer 被正确解密。
【讨论】:
以上是关于如何利用OpenSSL库进行RSA加密和解密的主要内容,如果未能解决你的问题,请参考以下文章