openssl入門編程

openkk 12年前發布 | 72K 次閱讀 安全相關 OpenSSL

1、Openssl --RSA加密算法的使用。

這兩天簡單的學習了一下openssl的使用。相關的介紹,可以在網上搜,挺多的。有些容易迷糊的概念,例如加密與身份驗證,什么時候用公鑰加密,什么時候用私鑰。如果學習過密碼學,應該很簡單理解,我沒學過,剛理解了些,趕緊記下,以防忘記。

用大家熟知C-S結構分析下吧:

首先請注意,公鑰和私鑰是一配一的,一個公鑰對應一個私鑰。

1)加密

客戶和服務器通信,服務器要保證與客戶通信的數據被保密,所以服務器會給客戶一個公鑰,客戶用此公鑰將自己的數據加密。然后將加密后的數據發給服務器,服務器用自己的私鑰解開密文還原成真的數據。公鑰是可以公開的,沒有必要保護它,因為你能用它加密,但是加密后,沒有私鑰,你確是無法解密的。即你沒法解開別人用此公鑰加密的數據。你也就無法知道別人的數據。

2)身份驗證

有時候服務器需要確定客戶端的身份,所以需要客戶端發送唯一的自己的標識,讓服務器確定自己的身份。如何發呢?這就用的到私鑰了。首先需要客戶端用自己的私鑰將特征碼加密后,將此數據發給服務器,服務器將使用你的公鑰對密文進行解密,如果解密成功可唯一確定這是用你的私鑰加密的密文。只要你不泄露私鑰,那么使用私鑰的人肯定是你。其實這個邏輯挺簡單的。

下面說我做的程序,主要是針對本地文件,對文件進行加密并解密。加密使用公鑰,解密使用私鑰。

主要使用的到函數為

1)密碼生成函數:

RSA *RSA_generate_key( int num,unsigned long e,void ((*callback)(int,int,void *)),void *cb_arg );

2)密鑰寫入文件函數

PEM_write_RSAPrivateKey();

3) 密鑰從文件中讀出函數

PEM_read_RSAPrivateKey()

4) 公鑰寫入文件函數

PEM_write_RSAPublicKey()

5)公鑰從文件中讀出函數

PEM_read_RSAPublicKey()

6)公鑰加密函數

RSA_public_encrypt()

7)私鑰解密函數

RSA_private_decrypt()

程序設計流程:

首先使用密碼生成函數生成公鑰和私鑰。

在用加密函數提取公鑰后對目標文件進行加密,生成新的加密文件。

再用解密文件提取私鑰后對加密文件進行解密操作。還原成原始文件,比較。為了現象更明顯,我使用的原始文件是一個可執行文件。在最終生成的還原文件測試時與原始文件的執行效果一樣。

    

當然在做實驗之前首先要安裝相關的庫,可以到項目主頁上下載http://www.openssl.org/source/ 。現在完之后,直接編譯安裝即可。

下面貼出實驗代碼:

1)生成密鑰文件,generatekey.c

#include <stdio.h>

#include <string.h>

#include <openssl/pem.h>

#define PUBKEYFILE "../pubkey.key"

#define PRIKEYFILE "../prikey.key"

int Prikey_Saveto_File(RSA *rsa,const char *filename);

int Pubkey_Saveto_File(RSA *rsa,const char *filename);

int main()

{

        RSA *key;

        FILE *fp_pub,*fp_pri;

        key=RSA_generate_key(1024,65537,NULL,NULL);

        if(NULL==key)

     {

                perror("generate_key error\n");

             exit(0);

     }

        if(!Prikey_Saveto_File(key,PRIKEYFILE))

     {

                perror("Prikey_Saveto_File() error\n");

             exit(0);

     }

        if(!Pubkey_Saveto_File(key,PUBKEYFILE))

     {

                perror("Pubkey_Saveto_File() error\n");

             exit(0);

     }

        printf("generate key OK\n");

        return 1;

}

/********************************************

 *write private key to file keyfile

 ********************************************/

int Prikey_Saveto_File(RSA *rsa,const char *filename)

{

        FILE *file;

        if (NULL == rsa)

     {

                printf("RSA not initial.\n");

                return 0;

     }

        file = fopen(filename,"wb");

        if (NULL == filename )

     {

                fprintf(stderr,"%s open error",filename);

                return 0;

     }

        PEM_write_RSAPrivateKey(file, rsa, NULL, NULL, 512, NULL, NULL);

        fclose(file);

        return 1;

}

/********************************************

 *write public key to file keyfile

 ********************************************/

int Pubkey_Saveto_File(RSA *rsa,const char *filename)

{

        FILE *file;

        if (NULL == rsa)

     {

                printf("RSA not initial.\n");

                return 0;

     }

        file = fopen(filename,"wb");

        if (NULL == file )

     {

                fprintf(stderr,"%s open error",filename);

                return 0;

     }

        PEM_write_RSAPublicKey(file, rsa);

        fclose(file);

        return 1;

}

2、加密文件encrypt.c

#include <openssl/md5.h>

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <string.h>

#include <stdio.h>

#if 0

#define TEST_FILE_PATH "./test/test"

#define OUT_FILE_PATH  "./test/jiami"

#endif 

#define PUB_KEY_PATH       "pubkey.key"

#define BUFSIZE  110

#define BUFSIZE1 2048

RSA* Pubkey_Getfrom_File(RSA *rsa,const char *filename);

int main(int argc,char **argv)

{

    RSA* key;

    char buf[BUFSIZE];

    char buf1[BUFSIZE1];

    int ret;

    FILE *fp,*fp0,*file;

    memset(buf,0,BUFSIZE);

    memset(buf1,0,BUFSIZE1);

    key=RSA_new();

    if(NULL==key)

    {

        perror("RSA_new()");

        exit(0);

    }

    if(argc<3)

    {

        perror("usage,input filein you needto encode and fileout\n");

        exit(0);

    }

    //read prikey

    key=Pubkey_Getfrom_File(key,PUB_KEY_PATH);

    if(NULL==key)

    {

        perror("Pubkey_Getfrom_File() wrong");

        exit(0);

    }

    //open relate file

    fp=fopen(argv[1]/*TEST_FILE_PATH*/,"r");

    if(fp==NULL)

    {

        perror("fopen() input wrong");

        exit(0);

    }

    fp0=fopen(argv[2]/*OUT_FILE_PATH*/,"w");

    if(fp0==NULL)

    {

        perror("fopen() output wrong");

        exit(0);

    }

    while((ret=fread(buf,sizeof(char),BUFSIZE,fp))==BUFSIZE)

    {//read string from file

        memset(buf1,0,BUFSIZE1);

        ret = RSA_public_encrypt(BUFSIZE, buf, buf1, 

                            key, RSA_PKCS1_PADDING);//en-code 

        if (ret<0)

     {

            perror("error in enc");

     }

        else

     {

            fwrite(buf1,sizeof(char),ret,fp0);//write string to file

     }

    }

    ret = RSA_public_encrypt(ret, buf, buf1, 

                    key, RSA_PKCS1_PADDING); //en-code

    if (ret<0)

    {

            perror("error in enc");

    }

    fwrite(buf1,sizeof(char),ret,fp0);//write string to file

    fclose(fp);

    fclose(fp0);

    RSA_free(key);//relase

    return 0;

}

/****************************************

 *read public key from file

 ****************************************/

RSA* Pubkey_Getfrom_File(RSA *rsa,const char *filename)

{

        FILE *file;

        if (NULL == rsa)

        {   

                printf("RSA not initial!\n");

                return NULL;

        }   

        file = fopen(filename, "rb");

        if (NULL == file)

        {   

                fprintf(stderr,"%s open error",filename);

                return NULL;

        }   

        rsa=PEM_read_RSAPublicKey(file,NULL, NULL, NULL);

        if(rsa==NULL)

     {

            perror("PEM_read_RSAPublicKey() ");

            fclose(file);

            return NULL;

     }

        fclose(file);

        return rsa;

}

3.解密文件decrypt.c

#include <openssl/md5.h>

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <string.h>

#include <stdio.h>

#if 0

#define TEST_FILE_PATH "./test/jiami"

#define OUT_FILE_PATH  "./test/jiemi"

#endif 

#define PRI_KEY_PATH       "prikey.key"

#define BUFSIZE  1024 

#define BUFSIZE1 2048

RSA* Prikey_Getfrom_File(RSA *rsa,const char *filename);

int main(int argc,char **argv)

{

    RSA* key;

    char buf[BUFSIZE];

    char buf1[BUFSIZE1];

    int ret,rsa_len;

    FILE *fp,*fp0,*file;

    memset(buf,0,BUFSIZE);

    memset(buf1,0,BUFSIZE1);

    if(argc<3)

    {

        perror("usage input file needto decode and outfile\n");

        exit(0);

    }

    key=RSA_new();

    if(NULL==key)

    {

        perror("RSA_new()");

        exit(0);

    }

    //read prikey

    key=Prikey_Getfrom_File(key,PRI_KEY_PATH);

    if(NULL==key)

    {

        perror("Prikey_Getfrom_File() wrong");

        exit(0);

    }

    //open relate file

    fp=fopen(argv[1]/*TEST_FILE_PATH*/,"r");

    if(fp==NULL)

    {

        perror("fopen() input wrong");

        exit(0);

    }

    fp0=fopen(argv[2]/*OUT_FILE_PATH*/,"w");

    if(fp0==NULL)

    {

        perror("fopen() output wrong");

        exit(0);

    }

    rsa_len=RSA_size(key);

    while((ret=fread(buf,sizeof(char),rsa_len,fp))==rsa_len)

    {//read string from file

        memset(buf1,0,BUFSIZE1);

        ret = RSA_private_decrypt(rsa_len, buf, buf1, 

                            key, RSA_PKCS1_PADDING);//de-code 

        if (ret<0)

     {

            perror("error in enc");

     }

        else

     {

            fwrite(buf1,sizeof(char),ret,fp0);//write string to file

     }

    }

    ret = RSA_private_decrypt(rsa_len, buf, buf1, 

                    key, RSA_PKCS1_PADDING); //de-code

    if (ret<0)

    {

            perror("error in enc");

    }

    fwrite(buf1,sizeof(char),ret,fp0);//write string to file



    fclose(fp);

    fclose(fp0);

    RSA_free(key);//relase

    return 0;

}

/****************************************

 *read private key from file

 ****************************************/

RSA* Prikey_Getfrom_File(RSA *rsa,const char *filename)

{

        FILE *file;

        if (NULL == rsa)

     {

                printf("RSA not initial!\n");

                return NULL;

     }

        file = fopen(filename, "rb");

        if (NULL == file)

     {

                fprintf(stderr,"%s open error",filename);

                return NULL;

     }

        rsa=PEM_read_RSAPrivateKey(file, NULL, NULL, NULL);

        if(rsa==NULL)

     {

            perror("PEM_read_RSAPrivateKey() wrong\n");

        fclose(file);

            return NULL;

     }

        fclose(file);

        return rsa;

}

注意解密函數的第一個參數,一定要多查看這兩個函數的參數的作用,不要急于寫代碼,否則事倍功半。加密的第一個參數如果大了,就會報錯。不知道為什么。暫時用到這么多,也不想深入了。以后如果用的話,就繼續弄吧。

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!