zoukankan      html  css  js  c++  java
  • openssl rsa 加解密

    <h4>1.openssl进行rsa加密解密</h4>
    首先介绍下命令台下openssl工具的简单使用:
    生成一个密钥:
    <pre lang="c" escaped="true" line="1">#openssl genrsa -out test.key 1024</pre>
    这里-out指定生成文件的。需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密。后面的1024是生成密钥的长度。

    openssl可以将这个文件中的公钥提取出来:
    <pre lang="c" escaped="true" line="1">#openssl rsa -in test.key -pubout -out test_pub.key</pre>
    <ul>

    <li>-in指定输入文件,</li>
    <li>-out指定提取生成公钥的文件名。</li>
    </ul>
    <strong>至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。</strong>

    我在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件:
    <pre lang="c" escaped="true" line="1">#openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en </pre>
    <ul>
    <li>-in指定要加密的文件,</li>
    <li>-inkey指定密钥,</li>
    <li>-pubin表明是用纯公钥文件加密,</li>
    <li>-out为加密后的文件。</li>
    </ul>


    解密文件:
    <pre lang="c" escaped="true" line="1">#openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de</pre>
    <ul>
    <li>-in指定被加密的文件,</li>
    <li>-inkey指定私钥文件,</li>
    <li>-out为解密后的文件。</li>
    </ul>


    至此,一次加密解密的过程告终。在实际使用中还可能包括证书,这个以后有机会再说~

    <h4>2.一些实例来看看</h4>
    下来介绍下在程序如何利用之前生成的test.key和test_pub.key来进行信息的加密与解密(当然也可以直接利用openssl的API来生成密钥文件)。

    下面是一个例子,这个例子利用已有的密钥来对source字符串进行加密与解密:

    <strong>例子1:</strong>
    <pre lang="c" escaped="true">

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<openssl/rsa.h>
    #include<openssl/pem.h>
    #include<openssl/err.h>
    #define OPENSSLKEY "test.key"
    #define PUBLICKEY "test_pub.key"
    #define BUFFSIZE 1024
    char* my_encrypt(char *str,char *path_key);//加密
    char* my_decrypt(char *str,char *path_key);//解密
    int main(void){
    char *source="i like dancing !";
    char *ptr_en,*ptr_de;
    printf("source is :%s ",source);
    ptr_en=my_encrypt(source,PUBLICKEY);
    printf("after encrypt:%s ",ptr_en);
    ptr_de=my_decrypt(ptr_en,OPENSSLKEY);
    printf("after decrypt:%s ",ptr_de);
    if(ptr_en!=NULL){
    free(ptr_en);
    }
    if(ptr_de!=NULL){
    free(ptr_de);
    }
    return 0;
    }
    char *my_encrypt(char *str,char *path_key){
    char *p_en;
    RSA *p_rsa;
    FILE *file;
    int flen,rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
    perror("open key file error");
    return NULL;
    }
    if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
    //if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){ 换成这句死活通不过,无论是否将公钥分离源文件
    ERR_print_errors_fp(stdout);
    return NULL;
    }
    flen=strlen(str);
    rsa_len=RSA_size(p_rsa);
    p_en=(unsigned char *)malloc(rsa_len+1);
    memset(p_en,0,rsa_len+1);
    if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
    return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_en;
    }
    char *my_decrypt(char *str,char *path_key){
    char *p_de;
    RSA *p_rsa;
    FILE *file;
    int rsa_len;
    if((file=fopen(path_key,"r"))==NULL){
    perror("open key file error");
    return NULL;
    }
    if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
    ERR_print_errors_fp(stdout);
    return NULL;
    }
    rsa_len=RSA_size(p_rsa);
    p_de=(unsigned char *)malloc(rsa_len+1);
    memset(p_de,0,rsa_len+1);
    if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
    return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
    return p_de;
    }
    </pre>

    <strong>例子2:</strong>

    <pre lang="c" escaped="true">

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <openssl/pem.h>
    #include <openssl/rsa.h>

    int main()
    {
    // 原始明文
    char plain[256]="测试测试,hello123";

    // 用来存放密文
    char encrypted[1024];

    // 用来存放解密后的明文
    char decrypted[1024];

    // 公钥和私钥文件
    const char* pub_key="public.pem";
    const char* priv_key="private.pem";

    // -------------------------------------------------------
    // 利用公钥加密明文的过程
    // -------------------------------------------------------

    // 打开公钥文件
    FILE* pub_fp=fopen(pub_key,"r");
    if(pub_fp==NULL){
    printf("failed to open pub_key file %s! ", pub_key);
    return -1;
    }

    // 从文件中读取公钥
    RSA* rsa1=PEM_read_RSA_PUBKEY(pub_fp, NULL, NULL, NULL);
    if(rsa1==NULL){
    printf("unable to read public key! ");
    return -1;
    }

    if(strlen(plain)>=RSA_size(rsa1)-41){
    printf("failed to encrypt ");
    return -1;
    }
    fclose(pub_fp);

    // 用公钥加密
    int len=RSA_public_encrypt(strlen(plain), plain, encrypted, rsa1, RSA_PKCS1_PADDING);
    if(len==-1 ){
    printf("failed to encrypt ");
    return -1;
    }

    // 输出加密后的密文
    FILE* fp=fopen("out.txt","w");
    if(fp){
    fwrite(encrypted,len,1,fp);
    fclose(fp);
    }
    // -------------------------------------------------------
    // 利用私钥解密密文的过程
    // -------------------------------------------------------
    // 打开私钥文件
    FILE* priv_fp=fopen(priv_key,"r");
    if(priv_fp==NULL){
    printf("failed to open priv_key file %s! ", priv_key);
    return -1;
    }

    // 从文件中读取私钥
    RSA *rsa2 = PEM_read_RSAPrivateKey(priv_fp, NULL, NULL, NULL);
    if(rsa2==NULL){
    printf("unable to read private key! ");
    return -1;
    }

    // 用私钥解密
    len=RSA_private_decrypt(len, encrypted, decrypted, rsa2, RSA_PKCS1_PADDING);
    if(len==-1){
    printf("failed to decrypt! ");
    return -1;
    }
    fclose(priv_fp);


    // 输出解密后的明文
    decrypted[len]=0;
    printf("%s ",decrypted);
    }
    </pre>

  • 相关阅读:
    Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task(枚举/最大连续子序列)
    Educational Codeforces Round 88 (Rated for Div. 2) A. Berland Poker(数学)
    Educational Codeforces Round 88 (Rated for Div. 2) E. Modular Stability(数论)
    Educational Codeforces Round 88 (Rated for Div. 2) C. Mixing Water(数学/二分)
    Codeforces Round #644 (Div. 3)
    Educational Codeforces Round 76 (Rated for Div. 2)
    Educational Codeforces Round 77 (Rated for Div. 2)
    Educational Codeforces Round 87 (Rated for Div. 2)
    AtCoder Beginner Contest 168
    Codeforces Round #643 (Div. 2)
  • 原文地址:https://www.cnblogs.com/liweilijie/p/4984076.html
Copyright © 2011-2022 走看看