您的位置:首页 > 其它

写一个RSA签名与验签的Demo

2015-12-28 15:07 302 查看
一、RSA私钥及公钥生成

OpenSSL工具安装

RSA私钥及公钥生成

OpenSSL工具安装

Linux用户(以Ubuntu为例)

sudo apt-get install openssl

RSA私钥及公钥生成

Linux用户(以Ubuntu为例)

$ openssl 进入OpenSSL程序

OpenSSL> genrsa -out rsa_private_key.pem 1024 生成私钥

OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥

OpenSSL> exit ## 退出OpenSSL程序

二、以下是Demo

签名验证签名函数原形:

/**

* @brief 签名函数

* text : 待签名字符串

* signature : 签名结果

* size : 分配存储签名结果内存大小

* sk_filename : 私钥文件名(pem格式,openssl直接生成的结果)

*/

char* alipay_rsa_sign(const char *text, char *signature, size_t size, const char *sk_filename)

/**

* @brief 验签函数

* text : 待验签字符串

* sig : 签名值

* pk_filename : 公钥文件名(pem格式,openssl直接生成的结果)

*/

int alipay_rsa_verify(const char *text, char *sig, const char *pk_filename)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

char *base64(const char *input, size_t length, char *result, size_t size)
{
BIO * bmem = NULL;
BIO * b64 = NULL;
BUF_MEM * bptr = NULL;
assert(NULL != input);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
if (NULL == b64 || NULL == bmem) {
perror("BIO_new");
return NULL;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);

if ((unsigned int)(bptr->length + 1) > size) {
BIO_free_all(b64);
return NULL;
}
memcpy(result, bptr->data, bptr->length);
result[bptr->length] = 0;

BIO_free_all(b64);

return result;
}

char *debase64(char *input, size_t length, char *result, size_t size)
{
BIO * b64 = NULL;
BIO * bmem = NULL;
assert(NULL != input);
if (length > size)
return NULL;
memset(result, 0, size);

b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(input, length);
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
if (NULL == b64 || NULL == bmem) {
perror("BIO_new");
return NULL;
}
bmem = BIO_push(b64, bmem);
BIO_read(bmem, result, length);

BIO_free_all(b64);

return result;
}

char *rsa_sign(const char *text, char *signature, size_t size, const char *sk_filename)
{
RSA *rsa;
unsigned char *sig;
unsigned int len;

assert(text != NULL && sk_filename != NULL);
OpenSSL_add_all_algorithms();
BIO* in = NULL;
in = BIO_new(BIO_s_file());
BIO_read_filename(in, sk_filename);
if (in == NULL) {
perror(sk_filename);
return NULL;
}

//将IO中数据以PEM格式读入EVP_PKEY结构中
rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
if (in != NULL)
BIO_free(in);
if (rsa == NULL) {
perror("PEM_read_bio_RSAPrivateKey");
return NULL;
}
if (NULL == (sig = (unsigned char*)malloc(RSA_size(rsa)))) {
RSA_free(rsa);
return NULL;
}

unsigned char sha1[20] = { '\0' };
//result len of sha1:20 bytes
SHA1((const unsigned char *)text, strlen(text), sha1);
if (1 != RSA_sign(NID_sha1, sha1, 20, sig, &len, rsa)) {
free(sig);
RSA_free(rsa);
printf("RSA_sign error.\n");
return NULL;
}
//base64((char *) sig, strlen((char *) sig), signature, size);
// do you know why can not use strlen
if (NULL == base64((char *)sig, 128, signature, size)) {
free(sig);
RSA_free(rsa);
printf("base64 error.\n");
return NULL;
}
free(sig);
RSA_free(rsa);

return signature;
}

int rsa_verify(const char *text, char *signature, const char *pk_filename)
{
RSA *rsa;
BIO* in = NULL;
assert(NULL != text && NULL != signature);
in = BIO_new(BIO_s_file());
BIO_read_filename(in, pk_filename);
if (NULL == in) {
printf("BIO_read_filename error.\n");
return 1;
}
//将IO中数据以PEM格式读入EVP_PKEY结构中
//rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);

if (in != NULL) BIO_free(in);
if (rsa == NULL) {
printf("PEM_read_bio_RSA_PUBKEY error.\n");
return 1;
}

//unsigned char sig_temp[250];
char * sig_debase = (char *)malloc(250 * sizeof(char));
if (NULL == debase64(signature, strlen((char *)signature), sig_debase, 250)) {
RSA_free(rsa);
printf("debase64 error.\n");
return 1;
}

unsigned char sha1[20];
SHA1((const unsigned char *)text, strlen(text), sha1);
if (1 != RSA_verify(NID_sha1, sha1, 20, (unsigned char *)sig_debase, 128, rsa)) {
free(sig_debase);
RSA_free(rsa);
printf("RSA_verify error.\n");
return 1;
}
free(sig_debase);
RSA_free(rsa);

return 0;
}

/*url enconding */
char *alpayex_URLencode(char *s, int len, int *new_length, char *start )
{
char c;
char *to;
unsigned char const *from, *end;
printf("len:%d\n", len);
from = s;
end = s + len;
/* start = to = (unsigned char *) malloc(3 * len + 1); */
to = start;
unsigned char hexchars[] = "0123456789ABCDEF";

while (from < end)
{
c = *from++;
if (c == ' ')
{
*to++ = '+';
}
else if ((c < '0' && c != '-' && c != '.')
||(c < 'A' && c > '9')
||(c > 'Z' && c < 'a' && c != '_')
||(c > 'z')) {
to[0] = '%';
to[1] = hexchars[((c >> 4)+16)%16];
to[2] = hexchars[c & 15];
to += 3;
}
else
{
*to++ = c;
}
}
*to = 0;
if (new_length)
{
*new_length = to - start;
}
return (char *) start;
}

int  main()
{
char *in="hello";
char out[20]={0};
int len=10;
base64(in,5,out,len);
printf("out = %s, len = %d \n",out,len);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: