/*rsa.c*/
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include<stdio.h>
#include<string.h>
#include"rsa.h"
//公钥加密
int
my_rsa_public_encrypt
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
des
,
int
*
deslen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
des
==
NULL
)
return
-
1
;
RSA
*
r
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
printf
(
"fopen [%s] error
\n
"
,
filename
);
return
-
2
;
}
if
(
PEM_read_RSA_PUBKEY
(
fp
,
&
r
,
0
,
0
)
==
NULL
)
{
fclose
(
fp
);
printf
(
"PEM_read_RSA_PUBKEY error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
//RSA_print_fp(stdout, r, 5);
//加密数据最大长度,是秘钥长度-11,加密结果,是RSA_size的返回值。
rsalen
=
RSA_size
(
r
)
-
11
;
unsigned
char
*
out
=
(
unsigned
char
*
)
malloc
(
rsalen
+
12
);
n
=
srclen
/
rsalen
;
for
(
i
=
0
;
i
<=
n
;
i
++
)
{
ienclen
=
(
i
!=
n
?
rsalen
:
srclen
%
(
rsalen
));
if
(
ienclen
==
0
)
break
;
memset
(
out
,
0
,
rsalen
+
12
);
ret
=
RSA_public_encrypt
(
ienclen
,
src
+
isrclen
,
out
,
r
,
RSA_PKCS1_PADDING
);
if
(
ret
<
0
)
{
printf
(
"RSA_public_encrypt failed,ret is [%d]
\n
"
,
ret
);
return
-
4
;
}
isrclen
+=
ienclen
;
memcpy
(
des
+
ideslen
,
out
,
ret
);
ideslen
+=
ret
;
}
des
[
ideslen
]
=
0
;
*
deslen
=
ideslen
;
free
(
out
);
RSA_free
(
r
);
CRYPTO_cleanup_all_ex_data
();
return
0
;
}
//私钥解密
int
my_rsa_prikey_decrypt
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
des
,
int
*
deslen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
des
==
NULL
)
return
-
1
;
RSA
*
r
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
printf
(
"fopen [%s] error
\n
"
,
filename
);
return
-
2
;
}
if
(
PEM_read_RSAPrivateKey
(
fp
,
&
r
,
0
,
0
)
==
NULL
)
{
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
//RSA_print_fp(stdout, r, 5);
rsalen
=
RSA_size
(
r
);
unsigned
char
*
out
=
(
unsigned
char
*
)
malloc
(
rsalen
+
1
);
n
=
srclen
/
rsalen
;
for
(
i
=
0
;
i
<=
n
;
i
++
)
{
ienclen
=
(
i
!=
n
?
rsalen
:
srclen
%
(
rsalen
));
if
(
ienclen
==
0
)
break
;
memset
(
out
,
0
,
rsalen
+
1
);
ret
=
RSA_private_decrypt
(
ienclen
,
src
+
isrclen
,
out
,
r
,
RSA_PKCS1_PADDING
);
if
(
ret
<
0
)
{
printf
(
"RSA_private_decrypt failed,ret is [%d]
\n
"
,
ret
);
return
-
4
;
}
isrclen
+=
ienclen
;
memcpy
(
des
+
ideslen
,
out
,
ret
);
ideslen
+=
ret
;
}
des
[
ideslen
]
=
0
;
*
deslen
=
ideslen
;
free
(
out
);
RSA_free
(
r
);
CRYPTO_cleanup_all_ex_data
();
return
0
;
}
//私钥加密
int
my_rsa_prikey_encrypt
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
des
,
int
*
deslen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
des
==
NULL
)
return
-
1
;
RSA
*
r
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
RSA_free
(
r
);
printf
(
"fopen [%s] error
\n
"
,
filename
);
return
-
2
;
}
if
(
PEM_read_RSAPrivateKey
(
fp
,
&
r
,
0
,
0
)
==
NULL
)
{
RSA_free
(
r
);
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
//RSA_print_fp(stdout, r, 5);
//加密数据最大长度,是秘钥长度-11,加密结果,是RSA_size的返回值。
rsalen
=
RSA_size
(
r
)
-
11
;
unsigned
char
*
out
=
(
unsigned
char
*
)
malloc
(
rsalen
+
12
);
n
=
srclen
/
rsalen
;
for
(
i
=
0
;
i
<=
n
;
i
++
)
{
ienclen
=
(
i
!=
n
?
rsalen
:
srclen
%
(
rsalen
));
if
(
ienclen
==
0
)
break
;
memset
(
out
,
0
,
rsalen
+
12
);
ret
=
RSA_private_encrypt
(
ienclen
,
src
+
isrclen
,
out
,
r
,
RSA_PKCS1_PADDING
);
if
(
ret
<
0
)
{
free
(
out
);
RSA_free
(
r
);
printf
(
"RSA_private_encrypt failed,ret is [%d]
\n
"
,
ret
);
return
-
4
;
}
isrclen
+=
ienclen
;
memcpy
(
des
+
ideslen
,
out
,
ret
);
ideslen
+=
ret
;
}
des
[
ideslen
]
=
0
;
*
deslen
=
ideslen
;
free
(
out
);
RSA_free
(
r
);
CRYPTO_cleanup_all_ex_data
();
return
0
;
}
//公钥解密
int
my_rsa_public_decrypt
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
des
,
int
*
deslen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
des
==
NULL
)
return
-
1
;
RSA
*
r
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
RSA_free
(
r
);
printf
(
"fopen [%s] error
\n
"
,
filename
);
return
-
2
;
}
if
(
PEM_read_RSA_PUBKEY
(
fp
,
&
r
,
0
,
0
)
==
NULL
)
{
RSA_free
(
r
);
fclose
(
fp
);
printf
(
"PEM_read_RSA_PUBKEY error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
//RSA_print_fp(stdout, r, 5);
rsalen
=
RSA_size
(
r
);
unsigned
char
*
out
=
(
unsigned
char
*
)
malloc
(
rsalen
+
1
);
n
=
srclen
/
rsalen
;
for
(
i
=
0
;
i
<=
n
;
i
++
)
{
ienclen
=
(
i
!=
n
?
rsalen
:
srclen
%
(
rsalen
));
if
(
ienclen
==
0
)
break
;
memset
(
out
,
0
,
rsalen
+
1
);
ret
=
RSA_public_decrypt
(
ienclen
,
src
+
isrclen
,
out
,
r
,
RSA_PKCS1_PADDING
);
if
(
ret
<
0
)
{
free
(
out
);
RSA_free
(
r
);
printf
(
"RSA_public_decrypt failed,ret is [%d]
\n
"
,
ret
);
return
-
4
;
}
isrclen
+=
ienclen
;
memcpy
(
des
+
ideslen
,
out
,
ret
);
ideslen
+=
ret
;
}
des
[
ideslen
]
=
0
;
*
deslen
=
ideslen
;
free
(
out
);
RSA_free
(
r
);
CRYPTO_cleanup_all_ex_data
();
return
0
;
}
//私钥签名
int
my_rsa_prikey_sign
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
sign
,
int
*
signlen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
sign
==
NULL
)
return
-
1
;
unsigned
char
hash
[
SHA_DIGEST_LENGTH
]
=
""
;
//unsigned sign_len = sizeof( sign );
RSA
*
rsa_pri_key
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
RSA_free
(
rsa_pri_key
);
printf
(
"fopen [%s] error
\n
"
,
filename
);
return
-
2
;
}
if
(
PEM_read_RSAPrivateKey
(
fp
,
&
rsa_pri_key
,
0
,
0
)
==
NULL
)
{
RSA_free
(
rsa_pri_key
);
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
SHA1
(
src
,
srclen
,
hash
);
ret
=
RSA_sign
(
NID_sha1
,
hash
,
SHA_DIGEST_LENGTH
,
sign
,
signlen
,
rsa_pri_key
);
if
(
1
!=
ret
)
{
RSA_free
(
rsa_pri_key
);
printf
(
"RSA_sign err,r is [%d],sign_len is [%d]
\n
"
,
ret
,
signlen
);
return
-
4
;
}
RSA_free
(
rsa_pri_key
);
return
0
;
}
//公钥签名验证
int
my_rsa_public_verify
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
sign
,
int
signlen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
sign
==
NULL
)
return
-
1
;
unsigned
char
hash
[
SHA_DIGEST_LENGTH
]
=
""
;
RSA
*
rsa_pub_key
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
RSA_free
(
rsa_pub_key
);
printf
(
"fopen [rsa_private_key] error
\n
"
);
return
-
2
;
}
if
(
!
PEM_read_RSA_PUBKEY
(
fp
,
&
rsa_pub_key
,
0
,
0
))
{
RSA_free
(
rsa_pub_key
);
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
SHA1
(
src
,
srclen
,
hash
);
ret
=
RSA_verify
(
NID_sha1
,
hash
,
SHA_DIGEST_LENGTH
,
sign
,
signlen
,
rsa_pub_key
);
if
(
1
!=
ret
)
{
RSA_free
(
rsa_pub_key
);
printf
(
"RSA_verify err,ret is [%d],sign_len is [%d]
\n
"
,
ret
,
signlen
);
return
-
4
;
}
printf
(
"RSA_verify ok
\n
"
);
RSA_free
(
rsa_pub_key
);
return
0
;
}
//私钥签名EVP
int
my_EVP_rsa_prikey_sign
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
sign
,
int
*
signlen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
sign
==
NULL
)
return
-
1
;
//RSA结构体变量
RSA
*
rsa_pri_key
=
RSA_new
();
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
printf
(
"fopen [rsa_private_key] error
\n
"
);
return
;
}
if
(
!
PEM_read_RSAPrivateKey
(
fp
,
&
rsa_pri_key
,
0
,
0
))
{
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
;
}
fclose
(
fp
);
//新建一个EVP_PKEY变量
EVP_PKEY
*
evpKey
=
EVP_PKEY_new
();
if
(
evpKey
==
NULL
)
{
printf
(
"EVP_PKEY_new err
\n
"
);
RSA_free
(
rsa_pri_key
);
return
;
}
if
(
EVP_PKEY_set1_RSA
(
evpKey
,
rsa_pri_key
)
!=
1
)
//保存RSA结构体到EVP_PKEY结构体
{
printf
(
"EVP_PKEY_set1_RSA err
\n
"
);
RSA_free
(
rsa_pri_key
);
EVP_PKEY_free
(
evpKey
);
return
;
}
//摘要算法上下文变量
EVP_MD_CTX
mdctx
;
//以下是计算签名代码
EVP_MD_CTX_init
(
&
mdctx
);
//初始化摘要上下文
if
(
!
EVP_SignInit_ex
(
&
mdctx
,
EVP_sha1
(),
NULL
))
//签名初始化,设置摘要算法,本例为sha1
{
printf
(
"err
\n
"
);
EVP_PKEY_free
(
evpKey
);
RSA_free
(
rsa_pri_key
);
return
;
}
if
(
!
EVP_SignUpdate
(
&
mdctx
,
src
,
srclen
))
//计算签名(摘要)Update
{
printf
(
"err
\n
"
);
EVP_PKEY_free
(
evpKey
);
RSA_free
(
rsa_pri_key
);
return
;
}
if
(
!
EVP_SignFinal
(
&
mdctx
,
sign
,
signlen
,
evpKey
))
//签名输出
{
printf
(
"err
\n
"
);
EVP_PKEY_free
(
evpKey
);
RSA_free
(
rsa_pri_key
);
return
;
}
/*printf("消息\"%s\"的签名值是: \n",src);
for(i = 0; i < *signlen; i++)
{
if(i%16==0)
printf("\n%08xH: ",i);
printf("%02x ", sign[i]);
}
printf("\n");
*/
//释放内存
EVP_PKEY_free
(
evpKey
);
RSA_free
(
rsa_pri_key
);
EVP_MD_CTX_cleanup
(
&
mdctx
);
}
//公钥签名EVP验证
int
my_EVP_rsa_public_verify
(
char
*
filename
,
unsigned
char
*
src
,
int
srclen
,
unsigned
char
*
sign
,
int
signlen
)
{
int
ret
=
0
,
isrclen
=
0
,
ideslen
=
0
,
i
=
0
,
n
=
0
,
ienclen
=
0
,
rsalen
=
0
;
if
(
filename
==
NULL
||
src
==
NULL
||
sign
==
NULL
)
return
-
1
;
//摘要算法上下文变量
EVP_MD_CTX
mdctx
;
RSA
*
rsa_pub_key
=
RSA_new
();
//rsa_public_key测试
FILE
*
fp
=
NULL
;
fp
=
fopen
(
filename
,
"rt"
);
if
(
fp
==
NULL
)
{
printf
(
"fopen [rsa_private_key] error
\n
"
);
return
-
2
;
}
if
(
!
PEM_read_RSA_PUBKEY
(
fp
,
&
rsa_pub_key
,
0
,
0
))
{
fclose
(
fp
);
printf
(
"PEM_read_RSAPrivateKey error
\n
"
);
return
-
3
;
}
fclose
(
fp
);
EVP_PKEY
*
pubKey
=
EVP_PKEY_new
();
//新建一个EVP_PKEY变量
if
(
pubKey
==
NULL
)
{
printf
(
"EVP_PKEY_new err
\n
"
);
RSA_free
(
rsa_pub_key
);
return
-
4
;
}
if
(
EVP_PKEY_set1_RSA
(
pubKey
,
rsa_pub_key
)
!=
1
)
//保存RSA结构体到EVP_PKEY结构体
{
printf
(
"EVP_PKEY_set1_RSA err
\n
"
);
RSA_free
(
rsa_pub_key
);
EVP_PKEY_free
(
pubKey
);
return
-
5
;
}
// printf("\n正在验证签名...\n");
//以下是验证签名代码
EVP_MD_CTX_init
(
&
mdctx
);
//初始化摘要上下文
if
(
!
EVP_VerifyInit_ex
(
&
mdctx
,
EVP_sha1
(),
NULL
))
//验证初始化,设置摘要算法,一定要和签名一致。
{
printf
(
"EVP_VerifyInit_ex err
\n
"
);
EVP_PKEY_free
(
pubKey
);
RSA_free
(
rsa_pub_key
);
return
-
6
;
}
if
(
!
EVP_VerifyUpdate
(
&
mdctx
,
src
,
srclen
))
//验证签名(摘要)Update
{
printf
(
"err
\n
"
);
EVP_PKEY_free
(
pubKey
);
RSA_free
(
rsa_pub_key
);
return
-
7
;
}
if
(
!
EVP_VerifyFinal
(
&
mdctx
,
sign
,
signlen
,
pubKey
))
//验证签名
{
printf
(
"verify err
\n
"
);
EVP_PKEY_free
(
pubKey
);
RSA_free
(
rsa_pub_key
);
return
-
8
;
}
//else
//{
// printf("验证签名正确.\n");
//}
EVP_PKEY_free
(
pubKey
);
RSA_free
(
rsa_pub_key
);
EVP_MD_CTX_cleanup
(
&
mdctx
);
return
0
;
}