注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

勇敢的劳尤条

 
 
 

日志

 
 

openssl之RSA编程(2)(产生公钥私钥文件以及加解密)  

2014-01-11 16:37:32|  分类: 软件安全以及传输 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
继上一篇openssl之RSA加密(1),继续RSA编程。
程序主要功能:生成RSA公钥私钥,并保存为文件。接着利用RSA公钥进行加密,私钥进行解密。

#include <stdio.h>
#include<string.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define MSG_LEN (128+1)
//打印函数,以16进制显示字符内容
void print_hex(char* buff)
{
    for (int i=0;buff[i];i++)
        printf("%02x",(unsigned char)buff[i]);
    printf("\n");
}
//生成RSA公钥和私钥文件
int createRSAPEM()
{
int ret=0;
BIO *bpub, *bpri;
    bpub = BIO_new_file("public.rsa", "w");
    if (!bpub)
        printf("failed to create public bio file\n");
    bpri = BIO_new_file("private.rsa", "w");
    if (!bpri)
        printf("failed to create private bio file\n");
    if (!bpub || !bpri) goto EXIT;

    RSA *pRSA;
    pRSA = RSA_generate_key( 1024, RSA_F4, NULL, NULL);
    if (pRSA != NULL)
    {
        if (!PEM_write_bio_RSAPublicKey(bpub, pRSA))//PEM_write_bio_RSA_PUBKEY
        {
            printf("PEM_write_bio_RSAPublicKey: failed\n");
            goto EXIT;
        }
        //if (!PEM_write_bio_RSAPrivateKey(bpri, pRSA, EVP_aes_256_cbc(), NULL, 0, NULL, NULL))
        if (!PEM_write_bio_RSAPrivateKey(bpri, pRSA, NULL, NULL, 0, NULL, NULL))//暂时设置密码
        {
            printf("PEM_write_bio_PrivateKey: failed\n");
            goto EXIT;
        }
        ret =1;
    }
EXIT:
    if (bpub)
        BIO_free(bpub);
    if (bpri)
        BIO_free(bpri);
    if (pRSA) RSA_free(pRSA);
    return ret;
}
//使用公钥加密
int rsa_encrypt(char *in, char *key_path, char* out)
{
    RSA *p_rsa;
    FILE *file;
    int rsa_len;
    if((file=fopen(key_path,"r"))==NULL){
        perror("open key file error");
        return 0;
    }
    //if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,&ccbb,NULL))==NULL){
    if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){
        ERR_print_errors_fp(stdout);
        return 0;
    }
    rsa_len=RSA_size(p_rsa);
    if(RSA_public_encrypt(rsa_len,(unsigned char*)in,(unsigned char*)out,p_rsa,RSA_NO_PADDING)<0){
        return 0;
    }
    RSA_free(p_rsa);
    fclose(file);
    return 1;
}
//使用私钥解密
int rsa_decrypt(char *in, char *key_path, char* out)
{
    RSA *p_rsa;
    FILE *file;
    int rsa_len;
    if((file=fopen(key_path,"r"))==NULL){
        perror("open key file error");
        return 0;
    }
    if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
        ERR_print_errors_fp(stdout);
        return 0;
    }
    rsa_len=RSA_size(p_rsa);
    if(RSA_private_decrypt(rsa_len,(unsigned char*)in,(unsigned char*)out,p_rsa,RSA_NO_PADDING)<0){
        return 0;
    }
    RSA_free(p_rsa);
    fclose(file);
    return 1;
}
int main(int argc,char**argv)
{
if(createRSAPEM())printf("OK!\n");
    char sourceStringTemp[MSG_LEN];
    char dstStringTemp[MSG_LEN];
    memset((char*)sourceStringTemp, 0 ,MSG_LEN);
    memset((char*)dstStringTemp, 0 ,MSG_LEN);

    strcpy((char*)sourceStringTemp, "123456789 123456789 123456789 12a");
    //strcpy((char*)sourceStringTemp, "1234love");
    char pubkey[]="public.rsa";
    char prikey[]="private.rsa";
    if(!rsa_encrypt(sourceStringTemp,pubkey,dstStringTemp))
    {
    printf("encrypt error\n");
    return -1;
    }
    printf("enc %d:",strlen((char*)dstStringTemp));
    print_hex(dstStringTemp);
    memset((char*)sourceStringTemp, 0 ,MSG_LEN);
    if(!rsa_decrypt(dstStringTemp,prikey,sourceStringTemp))
    {
    printf("decrypt error\n");
    return -1;
    }
    printf("dec %d:",strlen((char*)sourceStringTemp));
    printf("%s\n",sourceStringTemp);
    print_hex(sourceStringTemp);
    return 0;
}

利用上面的代码,实现了公钥加密,私钥解密的过程。下面时候示例:
openssl之RSA编程第二步(产生公钥私钥文件以及加解密) - yuanshuilee - 勇敢的劳尤条

        从上面的程序运行可以看出,公钥加密之后的密文, 每次都是不一样的,而且长度也不一样,但是标准长度应该是128字节,因为我生成的公钥私钥是1024bit,也就是128字节。由于密文128字节,所以设置buf为129字节,最后一个字节设置为0,作为结束符。(关于使用的环境,看推荐阅读)

这是官网给出的部分描述http://www.openssl.org/docs/crypto/RSA_public_encrypt.html#
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
RSA_public_encrypt() encrypts the flen bytes at from (usually a session key) using the public key rsa and stores the ciphertext in toto must point toRSA_size(rsa) bytes of memory.

      关于公钥私钥,看推荐博客。公钥加密,只能用私钥解密。私钥加密,只能用公钥解密,这是签名和认证。

参考资料:
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html#
  评论这张
 
阅读(2300)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017