2015-02-05 29 views
1

我正在使用openssl對字符串進行加密,並且得到以空字符結尾的字符串。我現在已經加密了字符串,我想通過使用base64編碼的網絡發送它。我只需要發送加密數據,如何在解密之前計算另一側字符串的長度?C/C++中以null結尾的字符串的長度

unsigned char *plaintext = (unsigned char*) "The quick brown fox jumps sover thes lazy dog"; 
unsigned char ciphertext[256] = {}; 
// After using openssl envelope_seal(), with EVP_aes_128_cbc() 
strlen((const char*)ciphertext) // length is different each time due to null terminated binary string 
sizeof(ciphertext) // lenght is equal to 256 
int envelope_seal() // gives me the length of that string as 48. 

請幫我計算ciphertext是48,但沒有在我所知的方法給我正確的輸出的長度。

+1

爲什麼不用字符串本身發送長度? – 2015-02-05 17:08:28

+0

我不知道密碼學的詳細信息,但是如果我需要發送加密文檔,那麼我在哪裏放長度?文件不夠? – Kahn 2015-02-05 17:14:12

+0

「發送加密文件」。通常當談到一個「文檔」時,包含原始二進制數據的char數組並不是立即想到的。如果你有後者,你需要的長度。如果你有一個「文件」,你首先要澄清這個詞的實際含義。 – 2015-02-05 17:27:42

回答

4

AES是分組密碼。它的塊大小爲16字節 - 這意味着如果你想用它加密一些數據,數據的長度必須是16的倍數(如果不是,你可能需要使用填充,比如說PKCS7,更多details) 。

現在你以後加密與AES(說字符串的長度爲32字節) - 你不能用strlen再拿到結果的長度,因爲結果,不是一個字符串了它是一些表示加密結果的字節數組。實際上,無論如何你都不需要知道長度,它將和明文一樣大小 - 我們在這裏說的是32個字節。

所以我認爲你沒有計算長度的問題了 - 現在如果對方應該知道密文的長度,你可以在包中提前發送長度(在我們的例子中是32)。另一方應該現在重建純文本(並且如果使用了一個,則還要刪除填充字節)。

注意:執行加密並獲得密文後,您可以對其應用base64編碼併發送它,但也可以發送代表密文的字節數組。

關於評論,我將嘗試簡要地強調這個過程如何進行。假設你有字符串char * str = "hello" - 這是5個字節,你需要加密它。就像我說的你不能直接加密它,你需要填充它以使16的倍數。爲此,你可以使用PKCS7填充(它類似於PKCS5,但是對於16字節塊)。現在,當您應用填充(例如,char * paddedText = PKCS7(str))時,您將以16字節的字節數組結束。

現在,沒有更多的問題。你可以加密這16個字節的明文。結果也將是16個字節的密文。

現在如果你想解密這16個字節的密文,你可以直接解密它(因爲它是16的倍數)。現在,由於PKCS7填充的工作方式,您可以輕鬆地從結果中得知只有前5個字節是原始字符串,並且您將刪除11個冗餘字節(PKCS5如何工作,請參閱我的鏈接-PKCS7中的內容與16字節塊長度),並獲得「hello」。

最後,我沒有看到問題出在哪裏,當你從客戶端發送到服務器時,你可以對消息長度進行編碼,例如,,分組爲16,因此接收方知道16個字節表示密文。但是,正如我所說的,使用這16個字節,解密後的接收器將能夠確定只有前5個字節是原始文本(由於使用了填充PKCS7)。所以不需要發送任何東西,除了16;在PKCS填充方案的幫助下,您將能夠知道只有前5個字節是純文本。

ps。在與OP進行了一些討論之後,似乎填充並不是他的主要問題,因爲使用的openssl方法似乎處理這個問題。

+0

+1有關填充問題的討論,其中,IMO從塊密碼中提取字符串長度至關重要,該密碼長度將長度限制爲16的倍數。 – chux 2015-02-05 18:21:21

+0

@chux:實際上,當密碼要求輸入爲16倍數的倍數時,你使16的明文倍數(如果不是)並加密它 - 然後一旦你嘗試解密密文,你需要知道原始字符串中有多少字節,這就是pkcs5出現的位置,例如 – 2015-02-05 18:26:44

+0

我怎麼知道在另一端加密數據是多久?我需要發送長度嗎?你有什麼建議? – Kahn 2015-02-05 19:05:08

1

如果數組中的有效數據沒有終止,那麼通過查看數組無法確定其長度。

如果envelope_seal告訴你長度,然後使用它,在需要長度的地方傳遞它。

+0

我有一個數據庫,我需要存儲加密值。我是否必須使用該屬性存儲每個屬性的長度?沒有其他辦法了? – Kahn 2015-02-05 17:16:06

+0

@Hesper:是的,如果你想存儲任意長度的任意數據,你必須指定長度。 – 2015-02-05 17:36:08

1

AES是分組密碼。因此,ciphertext的長度將爲您的plaintext模塊大小的長度,向上舍入爲最接近的塊大小。

+0

我假設我沒有純文本的情況下,我必須解碼加密的文本 – Kahn 2015-02-05 19:14:24

+1

好吧,當逆向(你給base64數據,你需要解碼和解密它),然後只分配一個緩衝base64數據的大小。解碼(仍然是加密的)數據將與base64編碼數據的大小相同或更小。 Base64解碼應該告訴你'ciphertext'的大小,因此你知道'純文本'究竟有多長(它仍然是AES塊大小的倍數)。然後,您需要通過了解填充類型或者是否存在大小字段或空終止符或什麼都需要計算明文「相關」數據的持續時間。 – inetknght 2015-02-05 19:18:19

相關問題