2013-01-09 32 views
2

我讀過如果要使用一種編程語言對字符串進行加密並使用其他編程語言對該字符串進行解密,那麼爲確保兼容性,最好在做加密。我已經讀過,這是加密字符串的字節數組而不是字符串本身的最佳做法。另外,我已經讀過某些加密算法,希望每個加密數據包的大小都是固定的。如果要加密的最後一個數據包不是所需的大小,則加密將失敗。因此,對首先轉換爲固定長度的數據(如十六進制)進行加密似乎是個不錯的主意。在不同編程語言之間傳遞加密數據的最佳實踐

我正在嘗試確定一般有用的最佳實踐,無論使用何種加密算法。爲了最大限度地提高兼容性加密和解密各種不同的語言和平臺的數據時,我想批判以下步驟的過程:

加密:

  • 開始使用純文本字符串
  • 純文本字符串轉換爲字節陣列
  • 轉換字節數組爲十六進制
  • 加密十六進制到加密的字符串
  • 端與加密的字符串

解密:

  • 開始具有加密串
  • 解密加密的字符串以十六進制
  • 轉換十六進制字節數組
  • 轉換字節數組純文本字符串
  • 以純文本字符串結尾

回答

0

我讀過這是加密字符串的字節數組而不是字符串本身的最佳做法。

加密算法通常適用於字節數組或字節流,所以是的。你不直接加密對象(字符串),你加密他們的字節表示。

此外,我已經讀過某些加密算法期望每個加密數據包都是固定長度的大小。如果要加密的最後一個數據包不是所需的大小,則加密將失敗。

這是您選擇的特定加密算法的實現細節。這真的取決於API接口對算法的作用。

一般來說,是的,加密算法會將輸入分解爲固定大小的塊。如果最後一個塊沒有滿,那麼它們可以用任意字節填充結尾以獲得完整的塊。爲了區分填充數據和剛好在末尾具有看起來像填充字節的數據,它們將前綴或附加純文本的長度到字節流。

這是一種不應該遺漏給用戶的細節,一個好的加密庫會爲你處理這些細節。理想情況下,您只需要輸入純文本字節並在另一側獲取加密字節。

因此,對首先被轉換爲固定長度的數據(如十六進制)進行加密似乎是個不錯的主意。

將字節轉換爲十六進制不會使其固定長度。它使尺寸加倍,但這不是固定的。它使它成爲ASCII碼安全的,因此它可以很容易地嵌入到文本文件和電子郵件中,但這與此無關。 (而Base64是一個更好的二進制→ ASCII編碼比十六進制反正。)

在查明爲了保證與加密和解密在不同的語言和平臺的數據兼容性最佳實踐的興趣,我想以下的批評步驟的過程:

加密:

  • 純文本字符串
  • 轉換純文本字符串字節陣列
  • 轉換字節數組爲十六進制
  • 加密十六進制到加密的字符串
  • 加密字符串
  • 純文本字節數組加密的字節數組

解密:

  • 加密字符串
  • 解密加密的字符串以十六進制
  • 轉換十六進制字節數組
  • 加密的字節數組
  • 解密加密的字節數組爲純文本字節數組
  • 轉換字節數組純文本字符串
  • 純文本字符串

要加密,請將純文本字符串轉換爲其字節表示,然後加密這些字節。結果將是一個加密的字節數組。

按照您選擇的方式將字節數組傳送到其他程序。

解密時,將加密的字節數組解密爲純文本字節數組。從這個字節數組構造你的字符串。完成。

2

你的前提是正確的,但在某些方面比這更容易一些。現代加密算法的目的是語言不可知的,並提供你有相同輸入與相同鍵,你應該得到相同的結果。

確實,對於大多數密碼和some modes,數據需要是固定長度。轉換爲十六進制不會這樣做,因爲數據需要在固定的邊界上結束。以AES爲例,如果要加密4個字節,則需要將其填充到16個字節,十六進制表示不會執行此操作。幸運的是,這很可能發生在您最終使用的加密API中,其標準爲padding schemes之一。由於您沒有標記語言,因此.NET中的AesManaged類支持填充模式的here's a list

另一方面,正確加密數據需要的不僅僅是字節編碼。您需要選擇正確的操作模式(首選CBC或CTR),然後提供某種類型的message integrity。單獨加密不能防止篡改數據。如果你想簡化一些東西,那麼看看GCM這樣的模式,它可以處理機密性和完整性。然後

你的方案應該是這個樣子:

  • 轉換的純文本字符串到字節數組。有關字符編碼的重要說明,請參閱@ rossum的評論。
  • 生成隨機的對稱密鑰或認證標籤使用PBKDF2到一個密碼轉換爲鍵
  • 生成中使用的隨機IV /隨機數與GCM
  • 加密的字節數組,並存儲它,沿着
  • 您可以選擇將字節數組存儲爲Base64 string

對於解密:

  • 如果存儲字節數組爲Base64字符串,convert back字節數組。
  • 解密加密的字節數組明文
  • 驗證所得認證標籤
  • 轉換字節數組爲純文本字符串匹配所存儲的認證標籤。
+1

當文本字符串轉換爲一個字節數組,或*反之亦然*確保指定正在使用的字符編碼。 UTF-8可能會從ANSI不同的結果或什麼是有任何重音的字符或周圍的其他特殊字符。 – rossum

+0

謝謝@rossum。應該補充一點。更新我的答案以引用您的評論。 – mfanto

0

真的加密的最佳實踐是使用高級加密框架,有很多事情你可以做錯誤的基本工作。如果你不使用高級加密框架,mfanto會提到你需要知道的重要事情。我猜測如果你試圖在編程語言中最大化兼容性,那是因爲你需要其他開發者與加密進行交互操作,然後他們需要學習使用加密的低級細節。

所以我對高級框架的建議是使用Google Keyczar框架,因爲它處理所有的細節,算法,密鑰管理,填充,iv,認證標籤,連線格式。它存在許多不同的編程Java, Python, C++,C#Go。一探究竟。

我寫的C#版本,所以我可以告訴你它使用幕後在大多數其他編程語言中廣泛使用的太元,並使用標準,如JSON用於密鑰管理和存儲。