openssl非常好的文章
1. http://www.cnblogs.com/phpinfo/archive/2013/08/09/3246376.html
// 其他可参考的:
1. http://blog.csdn.net/scape1989/article/details/18959657
2. http://blog.chinaunix.net/uid-23686726-id-3413979.html
////////////////////////
openssl利用rsa生成的公钥私钥加解密的C程序
// 参考:http://hayageek.com/rsa-encryption-decryption-openssl-c/
In this article, I have explained how to do RSA Encryption and Decryption with OpenSSL Library in C.
1).Generate RSA keys with OpenSSL
2).Public Encryption and Private Decryption
3).Private Encryption and Public Decryption.
4).Encryption and Decryption Example code.
1).GENERATE RSA KEYS WITH OPENSSL
Use the below command to generate RSA keys with length of 2048.
1
|
openssl genrsa -out
private
.pem 2048
|
Extract public key from private.pem with the following command.
1
|
openssl rsa -
in
private.pem -outform PEM -pubout -out public.pem
|
public.pem is RSA public key in PEM format.
private.pem is RSA private key in PEM format.
2).PUBLIC ENCRYPTION AND PRIVATE DECRYPTION
Below is the OpenSSL API for Public encryption and Private decryption.
1
2
3
4
5
|
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);
|
2.1 Preparing RSA Structure
For encryption and decryption we need to prepare RSA structure. Use the below function to create RSA with key buffer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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;
}
|
2.1 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.
1
2
3
4
5
6
7
8
|
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.
2.2 Private Decryption.
You can use the below method to decrypt the data with private key
1
2
3
4
5
6
|
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;
}
|
3).PRIVATE KEY ENCRYPTION AND PUBLIC KEY DECRYPTION.
Below is the OpenSSL API for private encryption and public decryption.
1
2
3
4
5
|
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.
3.1 Private Key Encryption.
You can use the below function for private key encryption.
1
2
3
4
5
6
|
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;
}
|
3.2 Public Key Decryption.
You can use the below function for public key decryption.
1
2
3
4
5
6
|
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;
}
|
4) ENCRYPTION AND DECRYPTION EXAMPLE CODE.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#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