一、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;
}