2016-10-30 95 views
1

我正在編程保險絲文件系統,我有一個問題。禁用AES密碼對象上的PKCS#7填充?

我使用CBC AES對磁盤中的數據進行加密。問題是填充。當密碼的大小例如是15個字節時是沒有問題的,因爲它增加了1個字節。問題是,當我試圖加密4096字節時,它也增加了16個字節的Padd,這對我來說是失敗的。我不知道爲什麼要添加填充,因爲4096是128的倍數(size aes block)。我需要修改我的C代碼說openssl,只有當它將是必要時添加填充,但不總是...

我知道,如果明文不是128的倍數,它將添加填充。但爲什麼不呢?我能做什麼?

這裏我密碼:

int encrypt_data(unsigned char *plaintext, int plaintext_len, unsigned char *key, 
       unsigned char *iv, unsigned char *ciphertext, int algorithm_pos) 
{ 
     EVP_CIPHER_CTX *ctx; 

     int len; 

     int ciphertext_len; 

     /* Create and initialise the context */ 
     if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); 

     /* Initialise the encryption operation. IMPORTANT - ensure you use a key 
     * and IV size appropriate for your cipher 
     * In this example we are using 256 bit AES (i.e. a 256 bit key). The 
     * IV size for *most* modes is the same as the block size. For AES this 
     * is 128 bits */ 
     if(1 != EVP_EncryptInit_ex(ctx, ciphers[algorithm_pos].algorithm(), NULL, key, iv)) 
       handleErrors(); 

     /* Provide the message to be encrypted, and obtain the encrypted output. 
     * EVP_EncryptUpdate can be called multiple times if necessary 
     */ 
     if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) 
       handleErrors(); 
     ciphertext_len = len; 

     /* Finalise the encryption. Further ciphertext bytes may be written at 
     * this stage. 
     */ 
     if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); 
     ciphertext_len += len; 

     /* Clean up */ 
     EVP_CIPHER_CTX_free(ctx); 

     return ciphertext_len; 
} 
+0

CBC模式只提供保密性,你通常要添加MAC安全使用CBC模式。您應該使用經過身份驗證的加密,因爲它提供了*機密性和真實性。請參閱OpenSSL wiki上的[EVP Authenticated Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption)。 – jww

回答

3

PKCS#7 padding。填充塊大小的確切倍數的原因是沒有辦法確定是否沒有填充,所以填充必須總是或永遠不要使用。考慮數據是4096字節還是最後一個字節是0x01。看起來像一個填充字節,但它不是,它是數據的一部分。

但是您應該使用磁盤扇區加密模式(如XTS),XTS僅建議用於全盤加密。這正是IEEE標準1619所設計的。

請參閱Explanation of the XTS Encryption Mode

而且NIST:The XTS-AES Mode for Confidentiality on Storage Devices

0

的問題是,當我試圖到加密4096個字節它也增加了我16個字節PADD的,它是失敗的我。我不知道爲什麼要添加填充,因爲4096是128的倍數(size aes block)。

正如Zaph所述,PKCS#7填充正在添加中。填充是確定性的,所以16個填充的確切倍數也被填充以確保去除。否則,廣義算法如何知道何時(1)純文本在16字節邊界上結束,與(2)純文本而不是以16字節邊界結尾並填充?

您可以使用EVP_CIPHER_CTX_ctrlEVP_CIPHER_CTX_set_padding禁用密碼對象上的填充行爲。 EVP_CIPHER_CTX_set_paddingEVP_CIPHER_CTX_ctrl的宏版本。這裏是什麼樣子:

int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding); 

從手冊頁:

EVP_CIPHER_CTX_set_padding()啓用或禁用填充。默認情況下,使用標準塊填充填充 加密操作,並在解密時檢查並刪除填充。如果填充參數 爲零,則不執行填充,則加密或解密的數據總量必須是塊大小的倍數或將發生錯誤。


我知道,如果明文不是128多個它會添加填充。但爲什麼不呢?我能做什麼?

禁用密碼上下文對象的填充。這裏的圖書館是如何做的:

$ grep -IR EVP_CIPHER_CTX_set_padding * 
CHANGES: *) New function EVP_CIPHER_CTX_set_padding() this is used to 
apps/enc.c:   EVP_CIPHER_CTX_set_padding(ctx, 0); 
apps/speed.c:    EVP_CIPHER_CTX_set_padding(&ctx, 0); 
crypto/cms/cms_pwri.c: EVP_CIPHER_CTX_set_padding(&kekctx, 0); 
crypto/evp/evp.h:int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); 
crypto/evp/evp_enc.c:int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) 
crypto/evp/evp_test.c:  EVP_CIPHER_CTX_set_padding(&ctx, 0); 
crypto/evp/evp_test.c:  EVP_CIPHER_CTX_set_padding(&ctx, 0);