rsa openssl実装


振り回して、今日はもともと自信満々でファイルに暗号化をして、とても速いと思って、結局探したいくつかのブログはバージョンが比較的に古いはずで、フォークを運行して、無理に諦めようとして、それから後で気づいたのは公式サイトで1つのdemoを探して、やっと無理でしょう例が現れました.
Opensslを呼び出すインタフェースかもしれませんが、全体的には簡単です.私は3つの部分を分けた.
  • は、4096ビットのスプーンペア(プライベートおよびパブリック)を生成して、ローカルファイルに
  • 保存する.
  • ファイルを公開暗号化する
  • プライベートを使用してファイルを復号する
  • .
    次は私の3つの対応するコードです.
    スプーンペアの生成(プライベートとパブリック)
    //gen.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    #define KEY_LENGTH 4096
    #define PUB_EXP 3
    #define PRINT_KEYS
    
    int main(void)
    {
        size_t pri_len;           // Length of private key
        size_t pub_len;           // Length of public key
        char *pri_key;            // Private key
        char *pub_key;            // Public key
    
        // Generate key pair
        printf("Generating RSA (%d bits) keypair...
    "
    , KEY_LENGTH); fflush(stdout); RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL); // To get the C-string PEM form: BIO *pri = BIO_new(BIO_s_mem()); BIO *pub = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL); PEM_write_bio_RSAPublicKey(pub, keypair); pri_len = BIO_pending(pri); pub_len = BIO_pending(pub); pri_key = malloc(pri_len + 1); pub_key = malloc(pub_len + 1); BIO_read(pri, pri_key, pri_len); BIO_read(pub, pub_key, pub_len); pri_key[pri_len] = '\0'; pub_key[pub_len] = '\0'; int fd_pri = open("key.pri", O_CREAT | O_WRONLY, 0400); int fd_pub = open("key.pub", O_CREAT | O_WRONLY, 0400); if(fd_pri < 0 || fd_pub < 0){ printf("error file![%d] - [%d]
    "
    , fd_pri, fd_pub); return -1; } write(fd_pri, pri_key, pri_len); write(fd_pub, pub_key, pub_len); close(fd_pri); close(fd_pub); return 0; }

    ファイルを公開暗号化する
    // en.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    #define KEY_LENGTH 4096
    #define PUB_EXP 3
    #define PRINT_KEYS
    // #define WRITE_TO_FILE
    #define PUB_FILE "key.pub"
    #define CFG_FILE "data.cfg"
    #define CFG_FILE_S "data_s.cfg"
    
    unsigned long get_file_size(const char *path)
    {
        unsigned long filesize = -1;
        struct stat statbuff;
        if (stat(path, &statbuff) < 0){
            return filesize;
        }
        else{
            filesize = statbuff.st_size;
        }
        return filesize;
    }
    
    int main(void)
    {
        char *pub_key;            // Public key
        char msg[KEY_LENGTH / 8]; // Message to encrypt
        char *encrypt = NULL;     // Encrypted message
        char *err;                // Buffer for any error messages
    
        int fp_pub;
        fp_pub = open(PUB_FILE, O_RDONLY);
        if (fp_pub < 0){
            printf("error file![%d]
    "
    , fp_pub); return -1; } size_t pub_len = get_file_size(PUB_FILE); pub_key = (char *)malloc(pub_len + 1); lseek(fp_pub, 0L, SEEK_SET); read(fp_pub, (void *)pub_key, pub_len); pub_key[pub_len] = '\0'; close(fp_pub); BIO *pub1 = BIO_new(BIO_s_mem()); if (NULL == pub1) return -1; BIO_puts(pub1, pub_key); RSA *keypair2 = PEM_read_bio_RSAPublicKey(pub1, NULL, NULL, NULL); #ifdef PRINT_KEYS printf("
    %s
    "
    , pub_key); #endif printf("done.
    "
    ); // Encrypt the message encrypt = malloc(RSA_size(keypair2)); int encrypt_len; err = malloc(130); int fp_l = open(CFG_FILE, O_RDONLY); if(fp_l <= 0) { printf("open cfg error!
    "
    ); return -1; } // if(access(CFG_FILE,0)==0){ // unlink(CFG_FILE); // } int fp_c = open(CFG_FILE_S, O_CREAT | O_WRONLY, 0600); if (fp_c <= 0){ printf("open cfg error!
    "
    ); return -1; } int len=0; while(1) { len = read(fp_l, msg, (KEY_LENGTH / 16) - 1); msg[len] = 0; printf(msg); if (len <= 0 || len > (KEY_LENGTH / 16) - 1) break; printf("
    len:%d %d
    "
    , len, (KEY_LENGTH / 16)); // write(pipe_id, buf, file_len); if ((encrypt_len = RSA_public_encrypt(len, (unsigned char *)msg, (unsigned char *)encrypt, keypair2, RSA_PKCS1_OAEP_PADDING)) == -1) { ERR_load_crypto_strings(); ERR_error_string(ERR_get_error(), err); fprintf(stderr, "Error encrypting message: %s
    "
    , err); goto free_stuff; } write(fp_c, encrypt, encrypt_len); printf("encrypt_len: %d
    "
    , encrypt_len); } free_stuff: RSA_free(keypair2); BIO_free_all(pub1); free(pub_key); free(encrypt); free(err); close(fp_c); close(fp_l); return 0; }

    秘密を使用してファイルを復号する
    // de.c
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    #define KEY_LENGTH 4096
    #define PUB_EXP 3
    #define PRINT_KEYS
    // #define WRITE_TO_FILE
    #define PRI_FILE "key.pri"
    #define CFG_FILE "data1.cfg"
    #define CFG_FILE_S "data_s.cfg"
    
    unsigned long get_file_size(const char *path)
    {
        unsigned long filesize = -1;
        struct stat statbuff;
        if (stat(path, &statbuff) < 0)
        {
            return filesize;
        }
        else
        {
            filesize = statbuff.st_size;
        }
        return filesize;
    }
    
    int main(void)
    {
        char *pri_key;            // Private key
        char msg[KEY_LENGTH / 8]; // Message to encrypt
        char *decrypt = NULL;     // Encrypted message
        char *err;                // Buffer for any error messages
    
        int fp_pri;
        fp_pri = open(PRI_FILE, O_RDONLY);
        if (fp_pri < 0)
        {
            printf("error file![%d]
    "
    , fp_pri); return -1; } size_t pri_len = get_file_size(PRI_FILE); pri_key = (char *)malloc(pri_len + 1); lseek(fp_pri, 0L, SEEK_SET); read(fp_pri, (void *)pri_key, pri_len); pri_key[pri_len] = '\0'; close(fp_pri); BIO *pri1 = BIO_new(BIO_s_mem()); if (NULL == pri1) return -1; BIO_puts(pri1, pri_key); RSA *keypair3 = PEM_read_bio_RSAPrivateKey(pri1, NULL, NULL, NULL); #ifdef PRINT_KEYS printf("
    %s
    "
    , pri_key); #endif printf("done.
    "
    ); decrypt = malloc(RSA_size(keypair3)); err = malloc(130); int fp_c = open(CFG_FILE_S, O_RDONLY); if (fp_c <= 0){ printf("open cfg error!
    "
    ); return -1; } int fp_l = open(CFG_FILE, O_CREAT | O_WRONLY, 0600); if (fp_l <= 0){ printf("open cfg error!
    "
    ); return -1; } int len = 0; while (1) { len = read(fp_c, msg, 512); msg[len] = 0; if (len <= 0 || len > 512) break; if ((len = RSA_private_decrypt(len, (unsigned char *)msg, (unsigned char *)decrypt, keypair3, RSA_PKCS1_OAEP_PADDING)) == -1) { ERR_load_crypto_strings(); ERR_error_string(ERR_get_error(), err); fprintf(stderr, "Error decrypting message: %s
    "
    , err); goto free_stuff; } decrypt[len] = 0; printf("
    %s
    %d %ld
    "
    , decrypt, len, strlen(decrypt)); write(fp_l, decrypt, strlen(decrypt)); } // printf(encrypt); free_stuff: RSA_free(keypair3); BIO_free_all(pri1); free(pri_key); free(decrypt); free(err); close(fp_c); close(fp_l); return 0; }

    また、この3つのファイルのコンパイルについて、簡単にmakefileを作りました.参考にしてください.
    gen:gen.c
    	gcc -ggdb -Wall -Wextra -o gen gen.c -lcrypto
    de: de.c
    	gcc -ggdb -Wall -Wextra -o de de.c -lcrypto
    en: en.c
    	gcc -ggdb -Wall -Wextra -o en en.c -lcrypto
    

    リファレンス
    OpenSSL APIを使用したセキュリティプログラミングSimple Public Key Encryption with RSA and OpenSSLは、demoが変更されているため、注釈が少なく、分からない場合はメッセージ交換が可能です.