1. 程式人生 > >利用openssl進行RSA加密解密例項

利用openssl進行RSA加密解密例項

轉載自:http://www.cnblogs.com/aLittleBitCool/archive/2011/09/22/2185418.html

openssl是一個功能強大的工具包,它集成了眾多密碼演算法及實用工具。我們即可以利用它提供的命令臺工具生成金鑰、證書來加密解密檔案,也可以在利用其提供的API介面在程式碼中對傳輸資訊進行加密。

RSA是一個非對稱加密演算法。簡單說來,非對稱加密演算法就是說加密解密一個檔案需要有兩個金鑰,一個用來加密,為公鑰,一個用來解密,為私鑰。證書可以用來授權公鑰的使用。

今天小研究了下openssl的rsa加密,其中主要涉及利用公鑰和金鑰加解密檔案,沒有涉及對證書的操作。想要集體瞭解的可以去:

---------------------------------------------------------------------------------------------------------------------

首先介紹下命令臺下openssl工具的簡單使用:

生成一個金鑰:

openssl genrsa -out test.key 1024

這裡-out指定生成檔案的。需要注意的是這個檔案包含了公鑰和金鑰兩部分,也就是說這個檔案即可用來加密也可以用來解密。後面的1024是生成金鑰的長度。

openssl可以將這個檔案中的公鑰提取出來:

openssl rsa -in
test.key -pubout -out test_pub.key

-in指定輸入檔案,-out指定提取生成公鑰的檔名。至此,我們手上就有了一個公鑰,一個私鑰(包含公鑰)。現在可以將用公鑰來加密檔案了。

我在目錄中建立一個hello的文字檔案,然後利用此前生成的公鑰加密檔案

openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en 

-in指定要加密的檔案,-inkey指定金鑰,-pubin表明是用純公鑰檔案加密,-out為加密後的檔案。

解密檔案:

openssl rsautl -decrypt -in
hello.en -inkey test.key -out hello.de

-in指定被加密的檔案,-inkey指定私鑰檔案,-out為解密後的檔案。

至此,一次加密解密的過程告終。在實際使用中還可能包括證書,這個以後有機會再說~

-------------------------------------------------------------------------------------------------------------------
下來介紹下在程式如何利用之前生成的test.key和test_pub.key來進行資訊的加密與解密(當然也可以直接利用openssl的API來生成金鑰檔案)。

下面是一個例子,這個例子利用已有的金鑰來對source字串進行加密與解密:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char* my_encrypt(char *str,char *path_key);//加密
char* my_decrypt(char *str,char *path_key);//解密
int main(void){
    char *source="i like dancing !";
    char *ptr_en,*ptr_de;
    printf("source is    :%s\n",source);
    ptr_en=my_encrypt(source,PUBLICKEY);
    printf("after encrypt:%s\n",ptr_en);
    ptr_de=my_decrypt(ptr_en,OPENSSLKEY);
    printf("after decrypt:%s\n",ptr_de);
    if(ptr_en!=NULL){
        free(ptr_en);
    }   
    if(ptr_de!=NULL){
        free(ptr_de);
    }   
    return 0;
}
char *my_encrypt(char *str,char *path_key){
    char *p_en;
    RSA *p_rsa;
    FILE *file;
    int flen,rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
        perror("open key file error");
        return NULL;    
    }   
    if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
    //if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){   換成這句死活通不過,無論是否將公鑰分離原始檔
        ERR_print_errors_fp(stdout);
        return NULL;
    }   
    flen=strlen(str);
    rsa_len=RSA_size(p_rsa);
    p_en=(unsigned char *)malloc(rsa_len+1);
    memset(p_en,0,rsa_len+1);
    if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
        return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_en;
}
char *my_decrypt(char *str,char *path_key){
    char *p_de;
    RSA *p_rsa;
    FILE *file;
    int rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
        perror("open key file error");
        return NULL;
    }
    if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
        ERR_print_errors_fp(stdout);
        return NULL;
    }
    rsa_len=RSA_size(p_rsa);
    p_de=(unsigned char *)malloc(rsa_len+1);
    memset(p_de,0,rsa_len+1);
    if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
        return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_de;
}


一個比較奇怪的問題:

37、38行中為從檔案中獲取金鑰,發現如果使用openssl提供的PEM_read_RSAPublicKey方法會一直失敗。

估計是檔案格式的問題~