openssl入门编程
来源:互联网 发布:mac无苹果安装win7系统 编辑:程序博客网 时间:2024/06/09 21:58
原文地址:http://www.open-open.com/lib/view/open1340107460237.html
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;
}
注意解密函数的第一个参数,一定要多查看这两个函数的参数的作用,不要急于写代码,否则事倍功半。加密的第一个参数如果大了,就会报错。不知道为什么。暂时用到这么多,也不想深入了。以后如果用的话,就继续弄吧。
- OpenSSL 编程入门
- openssl入门编程
- OpenSSL 编程入门
- OPENSSL编程入门学习
- openssl入门编程
- openssl入门编程
- OPENSSL编程入门学习
- OPENSSL编程入门学习
- socket编程之openssl入门
- Openssl 编程入门之 ssl编程
- OpenSSL编程入门(第一部分)
- openssl编程
- OpenSSL编程
- openssl编程
- openssl 编程
- openssl编程
- openssl编程
- OpenSSL编程
- Eclipse TestNG
- apt-get常用命令
- 关于字符串能不能修改,重指向的问题解释
- 剑指offer 16- 反转链表
- 西安治疗纤维瘤去哪个医院
- openssl入门编程
- Vijos-P1097-合并果子(简单贪心 && 优先队列 && c++)
- 逼真黑客范儿–Hacker Typer
- php创建接口出现乱码 encode urldecode转换程字符串
- ExtJs学习
- 一个菜鸟的Windows Phone开发日志
- init/main.c源码分析
- Android动画之Property Animation
- (大数据之zookeeper)ZooKeeper安装说明