2013-04-14 188 views
1

我正在使用openssl嘗試使用RSA公鑰來加密AES密鑰,並使用該AES通過HTTP將大數據發送到第三方站點。我知道這是很多加密技術,第二層出現在網絡關閉時,並且數據必須緩存在磁盤上,直到它可以是POST ed。從EVP_CIPHER_CTX獲取AES密鑰

我一直在使用的示例代碼this blog,一大塊,其中內聯如下:

int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx) 
{ 
    int i, nrounds = 5; 
    unsigned char key[32], iv[32]; 
    /* 
    * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material. 
    * nrounds is the number of times the we hash the material. More rounds are more secure but 
    * slower. 
    */ 
    i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv); 
    if (i != 32) { 
    printf("Key size is %d bits - should be 256 bits\n", i); 
    return -1; 
    } 
    for(int x = 0; x<32; ++x) 
    printf("Key: %x iv: %x \n", key[x], iv[x]); 
    for(int x = 0; x<8; ++x) 
    printf("salt: %x\n", salt[x]); 
    EVP_CIPHER_CTX_init(e_ctx); 
    EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv); 
    return 0; 
} 

我想堅持與他aes_init()功能,但我不能找到一種方法,一旦它被初始化,從EVP_CIPHER_CTX中獲得密鑰。

apropos列出有關EVP_CIPHER_CTX幾個功能:

$ apropos EVP_CIPHER_CTX 
EVP_CIPHER_CTX_block_size (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_cipher (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_cleanup (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_ctrl (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_flags (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_get_app_data (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_init (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_iv_length (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_key_length (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_mode (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_nid (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_set_app_data (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_set_key_length (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_set_padding (3ssl) - EVP cipher routines 
EVP_CIPHER_CTX_type (3ssl) - EVP cipher routines 

EVP_CIPHER_CTX_set_key_length看起來很有希望,但有那麼一些神奇的偏移從我讀EVP_CIPHER_CTX?否則,我將不得不修改其功能以返回key(和iv),或丟棄該函數並內聯代碼。

這裏的最終目標是使用AES加密大部分數據,並使用我們的RSA公鑰對base64密碼進行加密,然後將它們廣播到服務器。 (我相信這是正確的做事方式)

唯一的問題是,從EVP_CIPHER_CTX中提取密鑰。

+0

爲什麼密鑰和IV不是密鑰和IV,你正在尋找 – doptimusprime

+0

我只是需要足夠的解密它在th? e另一面 –

+0

我是否只需要key_data和salt? –

回答

2

爲什麼要爲這種混合密碼構建自己的解決方案?現有的標準和方法可以幫助您。

我建議你看一下PKCS#7標準,這是S/MIME的基礎。 OpenSSL有一個直接的接口。您可以使用非對稱密鑰來告訴您要加密哪些數據,併爲您處理剩餘的數據。

請看pkcs7_encryptpkcs7_decrypt以及i2d_PKCS7_*如何將數據提取爲可傳輸格式(和d2i_PKCS7_*反向)。請參閱OpenSSL的文檔:PKCS7_encryptPKCS7_decrypt你可能需要熟悉與OpenSSL的使用i2d/d2i convention(這是X509,但D2I部分在這裏也適用

編輯:這裏是加密的一個例子(解密類似):

#include <stdio.h> 
#include <openssl/pem.h> 
#include <openssl/crypto.h> 
#include <openssl/err.h> 


int main() 
{ 
    STACK_OF(X509) *certs; 
    FILE *fp; 
    BIO *bio; 
    PKCS7 *p7; 

    ERR_load_crypto_strings(); 
    OpenSSL_add_all_algorithms(); 

    certs = sk_X509_new_null(); 
    fp = fopen("cert.pem", "r"); 
    sk_X509_push(certs, PEM_read_X509(fp, NULL, NULL, NULL)); 
    fclose(fp); 

    bio = BIO_new_file("data.txt", "r"); 
    p7 = PKCS7_encrypt(certs, bio, EVP_des_ede3_cbc(), 0); 
    BIO_free(bio); 

    bio = BIO_new_file("data.txt.enc", "w"); 
    i2d_PKCS7_bio(bio, p7); 
    BIO_flush(bio); 
    BIO_free(bio); 

    ERR_print_errors_fp(stdout); 
    return 0; 
} 

我已經上傳了完整的例子來my repository

+0

嗨javex,謝謝你的迴應。我欣賞小費!我探索了SMIME,但是多部分發布等的想法看起來與我所需要的相反。如果我可以簡化我的代碼,那麼越好。 –

+0

假設我可以使用RSA公鑰加密任意大小,然後的數據塊的一位同事被告知正確的解決方案是使用RSA加密AES密鑰,並加密後我會在這個方向我的數據與該密鑰。使用標準解決方案我會更快樂。 –

+0

而且,我在我的內聯德'/ d2i'格式鑰匙到我的項目的目標文件,所以我已經部分地在這條道路! –