您的位置:首页 > 编程语言

openssl入门编程

2020-05-10 04:19 106 查看

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;

}
[/code]

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;

}
[/code]

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;

}
[/code]

注意解密函数的第一个参数,一定要多查看这两个函数的参数的作用,不要急于写代码,否则事倍功半。加密的第一个参数如果大了,就会报错。不知道为什么。暂时用到这么多,也不想深入了。以后如果用的话,就继续弄吧。工程目录:

转载于:https://my.oschina.net/shangyu/blog/62920

chinong5099 原创文章 0获赞 0访问量 29 关注 私信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: