Ubuntu16.04 使用OpenSSL库实现RSA

来源:互联网 发布:阿尔法软件官方下载 编辑:程序博客网 时间:2024/05/21 21:49

一、Ubuntu安装OpenSSL开发包
Ubuntu已经安装过openssl但是仍然不能进行openssl编程
需安装openssl-devel包。
Ubuntu16.04下安装OpenSSL库
sudo apt-get install openssl
sudo apt-get install libssl-dev

二、编写C代码,实现RSA接口
1、代码实现:
1、Public Encryption and Private Decryption
Below is the OpenSSL API for Public encryption and Private decryption.

int RSA_public_encrypt(int flen, unsigned char *from,   unsigned char *to, RSA *rsa, int padding);int RSA_private_decrypt(int flen, unsigned char *from,    unsigned char *to, RSA *rsa, int padding);

1.1 Preparing RSA Structure
For encryption and decryption we need to prepare RSA structure. Use the below function to create RSA with key buffer.

RSA * createRSA(unsigned char * key,int public){    RSA *rsa= NULL;    BIO *keybio ;    keybio = BIO_new_mem_buf(key, -1);    if (keybio==NULL)    {        printf( "Failed to create key BIO");        return 0;    }    if(public)    {        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);    }    else    {        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);    }    return rsa;}

Usage for public key: createRSA(“PUBLIC_KEY_BUFFER”,1);
Usage for private key: createRSA(“PRIVATE_KEY_BUFFER”,0);

If you want to create RSA with key file name, you can use this function

RSA * createRSAWithFilename(char * filename,int public){    FILE * fp = fopen(filename,"rb");    if(fp == NULL)    {        printf("Unable to open file %s \n",filename);        return NULL;        }    RSA *rsa= RSA_new() ;    if(public)    {        rsa = PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL);    }    else    {        rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL);    }    return rsa;}

1.2 Public Key Encryption.
For encryption we can use padding, below is the list of supported paddings.

RSA_PKCS1_PADDING
PKCS #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.

You can use the below method, to encrypt the data with public key.

int padding = RSA_PKCS1_PADDING;int public_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted){    RSA * rsa = createRSA(key,1);    int result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);    return result;}

Note: public key encryption supports all the paddings.

1.3 Private Decryption.
You can use the below method to decrypt the data with private key

int private_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted){    RSA * rsa = createRSA(key,0);    int  result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);    return result;}

2、Private Key Encryption and Public Key Decryption.
Below is the OpenSSL API for private encryption and public decryption.

int RSA_private_encrypt(int flen, unsigned char *from,   unsigned char *to, RSA *rsa, int padding);int RSA_public_decrypt(int flen, unsigned char *from,   unsigned char *to, RSA *rsa, int padding);

Note: private key encryption supports only these paddings. RSA_PKCS1_PADDING and RSA_NO_PADDING.

2.1 Private Key Encryption.
You can use the below function for private key encryption.

int private_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted){    RSA * rsa = createRSA(key,0);    int result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);    return result;}

2.2 Public Key Decryption.
You can use the below function for public key decryption.

int public_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted){    RSA * rsa = createRSA(key,1);    int  result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);    return result;}

3) Encryption and Decryption Example code.

#include <openssl/pem.h>#include <openssl/ssl.h>#include <openssl/rsa.h>#include <openssl/evp.h>#include <openssl/bio.h>#include <openssl/err.h>#include <stdio.h>int padding = RSA_PKCS1_PADDING;RSA * createRSA(unsigned char * key,int public){    RSA *rsa= NULL;    BIO *keybio ;    keybio = BIO_new_mem_buf(key, -1);    if (keybio==NULL)    {        printf( "Failed to create key BIO");        return 0;    }    if(public)    {        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);    }    else    {        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);    }    if(rsa == NULL)    {        printf( "Failed to create RSA");    }    return rsa;}int public_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted){    RSA * rsa = createRSA(key,1);    int result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);    return result;}int private_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted){    RSA * rsa = createRSA(key,0);    int  result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);    return result;}int private_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted){    RSA * rsa = createRSA(key,0);    int result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);    return result;}int public_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted){    RSA * rsa = createRSA(key,1);    int  result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);    return result;}void printLastError(char *msg){    char * err = malloc(130);;    ERR_load_crypto_strings();    ERR_error_string(ERR_get_error(), err);    printf("%s ERROR: %s\n",msg, err);    free(err);}int main(){  char plainText[2048/8] = "Hello this is Ravi"; //key length : 2048 char publicKey[]="-----BEGIN PUBLIC KEY-----\n"\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"\"ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n"\"vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n"\"fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n"\"i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n"\"PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n"\"wQIDAQAB\n"\"-----END PUBLIC KEY-----\n"; char privateKey[]="-----BEGIN RSA PRIVATE KEY-----\n"\"MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"\"vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9\n"\"Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9\n"\"yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l\n"\"WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q\n"\"gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8\n"\"omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e\n"\"N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG\n"\"X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd\n"\"gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl\n"\"vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF\n"\"1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu\n"\"m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ\n"\"uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D\n"\"JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D\n"\"4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV\n"\"WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5\n"\"nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG\n"\"PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA\n"\"SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1\n"\"I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96\n"\"ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF\n"\"yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5\n"\"w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX\n"\"uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw\n"\"-----END RSA PRIVATE KEY-----\n";unsigned char  encrypted[4098]={};unsigned char decrypted[4098]={};int encrypted_length= public_encrypt(plainText,strlen(plainText),publicKey,encrypted);if(encrypted_length == -1){    printLastError("Public Encrypt failed ");    exit(0);}printf("Encrypted length =%d\n",encrypted_length);int decrypted_length = private_decrypt(encrypted,encrypted_length,privateKey, decrypted);if(decrypted_length == -1){    printLastError("Private Decrypt failed ");    exit(0);}printf("Decrypted Text =%s\n",decrypted);printf("Decrypted Length =%d\n",decrypted_length);encrypted_length= private_encrypt(plainText,strlen(plainText),privateKey,encrypted);if(encrypted_length == -1){    printLastError("Private Encrypt failed");    exit(0);}printf("Encrypted length =%d\n",encrypted_length);decrypted_length = public_decrypt(encrypted,encrypted_length,publicKey, decrypted);if(decrypted_length == -1){    printLastError("Public Decrypt failed");    exit(0);}printf("Decrypted Text =%s\n",decrypted);printf("Decrypted Length =%d\n",decrypted_length);}

Reference:openssl documentaion
代码转自:http://hayageek.com/rsa-encryption-decryption-openssl-c/#private-encrypt
参考:http://www.qmailer.net/archives/216.html

2、引用OpenSSL的动态库,将上述代码编译成.so文件

不管什么库文件,都既要在包含.h文件(不然编译通不过:有未声明的函数),也要在gcc选项里面指定.so文件的位置(不然链接通不过:未知的符号)

gcc -c -g -fPIC -O2 rsa.c -I include_path -I lib_path
gcc -shared -o./libRSA.so rsa.o -L lib_path -lcrypto

include_path 改成你所编译的库文件头文件的目录
lib_path 改成应用的OpenSSL动态库文件的目录
libRSA.so 改成你所编译的库文件名字
-lcrypto OpenSSL动态库的名字

第一条编译指令,引用OpenSSL的动态库将rsa.c编译为rsa.o
第二条编译指令,将rsa.o文件编译为动态库libRSA.so

三、Python调用.so,执行加解密
1、将yourlib.so与Python脚本放在同一文件夹;
2、Python引用.so代码如下:

import ctypes ll = ctypes.cdll.LoadLibrary   MyRSA = ll("./libRSA.so") res = MyRSA.main() print str(res)

3、生成公私钥对

os.system('openssl genrsa -out private.pem 2048')os.system('openssl rsa -in private.pem -outform PEM -pubout -out public.pem')

以上代码便可执行以上C代码实现的main函数(Encryption and Decryption Example code),执行一个rsa加解密的例子。

0 0
原创粉丝点击