2012-12-12 62 views
3

我寫了一個程序,一個字符串PolarSSL AES-CBC後我加密字符串PolarSSL AES-CBC

這是我的代碼

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <polarssl/aes.h> 
#include <polarssl/havege.h> 

int main() 
{ 
    char buff[2][64] = {"Who can tell me WHY?", ""}; 
    havege_state hs; 
    int retval; 
    unsigned char IV[16]; 

    aes_context enc_ctx; 
    aes_context dec_ctx; 

    aes_setkey_enc(&enc_ctx, "password", 256); 
    aes_setkey_dec(&dec_ctx, "password", 256); 

    havege_init(&hs); 
    havege_random(&hs, IV, 16); 

    //encrypt 
    aes_crypt_cbc(&enc_ctx, AES_ENCRYPT, 64, IV, buff[0], buff[1]); 
    havege_random(&hs, IV, 16); 

    //decrypt 
    aes_crypt_cbc(&dec_ctx, AES_DECRYPT, 64, IV, buff[1],buff[0]); 

    printf("After decrypt:%s\n", buff[0]); 
    return 0; 
} 

加密但是當我運行它,我不能解密字符串,解密後我剛收到錯誤的文字。

我不明白AES算法,因爲我的英文很糟糕,閱讀一些文章太難了。

------------------------- Added by midCat ------------------ --------------------------

我跟着你的意見,並改變我的代碼 現在我使用相同的IV和256位關鍵,這是新代碼

int main() 
{ 
    char buff[2][64] = {"ABCDEFGHIJKLMN", ""}; 
    havege_state hs; 
    int retval; 
    unsigned char IV[16]; 
    unsigned char IV2[16]; 
    unsigned char key[32]; 

    aes_context enc_ctx; 
    aes_context dec_ctx; 

    havege_init(&hs); 
    havege_random(&hs, IV, 16); 
    havege_random(&hs, key, 32); 
    strncpy(IV, IV2, 16);   //copy IV 

    aes_setkey_enc(&enc_ctx, key, 256); 
    aes_setkey_dec(&dec_ctx, key, 256); 


    //encrypt 
    aes_crypt_cbc(&enc_ctx, AES_ENCRYPT, 64, IV, buff[0], buff[1]); 
    printf("Before encrypt:%s\n", buff[0]); 

    //decrypt 
    aes_crypt_cbc(&dec_ctx, AES_DECRYPT, 64, IV2, buff[1],buff[0]); 
    printf("After decrypt:%s\n", buff[0]); 
    return 0; 
} 

我編譯它,並運行多次,得到了相同的輸出:

Before encrypt:ABCDEFGHIJKLMN 
After decrypt:ABCDEFGHYC 
         LMN 

如何得到IV

+0

AES適用於字節而不是字符..有一個細微的區別..您不能使用strncpy()來複制IV。您必須使用memcpy()作爲IV ** CAN **包含NULL字符。其餘的,這段代碼是可以的(並且可以在我的機器上運行)。 – Paul

+0

你也換了源和目標操作數,你想使用memcpy(IV2,IV,sizeof(IV)) – dnaq

回答

4

編輯:正如Daniel在他的回答中指出的那樣,一個大問題是你試圖用一個隨機IV來解密(這不會給你你期望的結果)。不過,我建議你閱讀這個答案的其餘部分。

首先,aes_set_key_encaes_set_key_dec不需要密碼作爲輸入,他們拿鑰匙。只要密鑰長度(在你的情況下是32字節的隨機字符串,因爲你想使用256位密鑰),密鑰應該是一個完全隨機的值。

在你的情況下,你用一個簡短密碼呼叫aes_set_key_enc/aes_set_key_dec,但告訴它它應該期望一個256位密鑰,這將導致這些函數使用密碼以外的內存作爲密鑰的一部分,並將導致加密和解密密鑰不同。回顧一下,AES(或任何密碼算法)需要隨機密鑰,算法本身沒有將密碼擴展到密鑰的概念。

如果您想使用密碼作爲密鑰,您需要一些將非隨機密碼擴展爲僞隨機密鑰的功能。唯一可行的方法是使用一種旨在加密安全的功能,但也很慢,這是爲了減輕暴力攻擊密碼的風險。

良好的功能,使用的都是科林Percivals scryptbcrypt或 ,我會建議scrypt最PBKDF2

但是,我想強調,你可能不應該在這個抽象層次上工作。您正在使用的基元(分組密碼,CBC模式)處於非常低的抽象級別,並且使用這些基元構建密碼系統可能非常危險。例如,您不使用密文的任何類型的身份驗證,這可能會打開您的實現選擇密文攻擊。

我認爲如果你想在你的應用程序中使用加密技術的最佳方式是嘗試在更高的抽象層次上工作,例如使用Dan Bernsteins出色的NaCl或谷歌KeyCzar

回顧一下,您的具體問題可以通過使用256位密鑰來解決,但是您應該考慮在這個抽象級別實現您自己的密碼系統。

+0

這是非常好的建議,我同意100%。但是,很可能(取決於編譯器)不是問題的真正根源。 –

+0

你是對的,我錯過了他正在使用隨機四進行解密。 – dnaq

+0

PolarSSL包含一個用於PBKDF2的模塊。因此,與此代碼結合使用時,這很可能是最好的。 (除了IV事情最有可能是問題的原因) – Paul

4

您正在使用隨機IV進行解密。那是錯的。您需要與用於加密的解密相同的IV。只需刪除第二個電話

havege_random(&hs, IV, 16); 

之間的加密和解密。

此外,請確保使用32字節的字符數組作爲aes_setkey_encaes_setkey_dec的第二個參數,因爲您正在讀取字符串的末尾,如同現在一樣。根據編譯器的不同,它可能會導致不同的密鑰被用於加密和解密(並因此失敗)。

(編輯了問題的後半部分)

更改此:

strncpy(IV, IV2, 16);   //copy IV 

這樣:

memcpy(IV2, IV, 16);   //copy IV 

這是memcpy而不是strncpy因爲IV是可以包含隨機數據字符串終結符'\0',這兩個函數的第一個參數是目標,而不是sou RCE。你從IV2複製一個字符串到IV而不是從IV到IV2的內存。

並回答如何獲得解密IV的問題:通常,IV只是與密文一起發送。每個IV只能使用一次,並且不能被預測,但沒有必要保密。一個常見的構造是爲每條消息選擇一個隨機IV,並根據場景簡單地將IV附加到密文或將其存儲在文件頭中。

這就是說,我同意建議您不要使用加密原語構建自己的加密協議,除非您知道自己在做什麼。

+0

我遵循你的建議,但仍然有錯誤的文字。我剛剛粘貼了我的新代碼。 – midCat

+1

看我的編輯。你得到了strncpy的參數順序錯誤,你需要使用memcpy。 –

-1

我只是在

aes_crypt_cbc(&dec_ctx, AES_DECRYPT, 64, IV2, buff[1],buff[0]); 

改爲64到14和每一件事工作得很好!