2009-05-19 114 views
24

因此,在CodingHorror's fun with encryption和抖動評論之後,我們正在重新考慮做我們自己的加密。如何開始使用BouncyCastle?

在這種情況下,我們需要將標識用戶的一些信息傳遞給第三方服務,然後第三方服務將回調到我們網站上的服務並附帶信息和散列。

第二個服務查找該用戶的信息,然後將其傳遞迴第三方服務。

我們想要加密這個進入第三方服務的用戶信息,並在它出來後將其解密。所以這不是一個長期的加密。

在編碼恐怖文章中,Coda Hale推薦BouncyCastle和庫中的高層抽象來針對特定需求進行加密。

我的問題是BouncyCastle命名空間很大,文檔是不存在的。任何人都可以將我指向這個高級抽象庫嗎? (或者除了BouncyCastle之外還有其他選擇嗎?)

+5

重新考慮寫自己的加密的lib?好的選擇! – Cheeso 2009-05-19 23:21:07

+0

儘管BouncyCastle沒有太多的文檔,但我發現他們的郵件列表非常有幫助http://www.bouncycastle.org/csharpdevmailarchive/index.html。您也可以訂閱提問。 您還應該獲取它附帶的示例和測試的源代碼,它們涵蓋了大多數使用案例。 – Emmanuel 2009-05-21 16:02:14

+0

您所描述的內容聽起來像是OAuth的典型用例 - 您是否考慮過使用它? – 2011-09-26 01:21:16

回答

10

高層抽象?我想在充氣城堡庫中的最高級別抽象將包括:

我大多熟悉庫的Java版本。或許此代碼段將爲您提供適合您的需要足夠高的抽象(例如使用AES-256加密):

public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException { 
    assert key.length == 32; // 32 bytes == 256 bits 
    CipherParameters cipherParameters = new KeyParameter(key); 

    /* 
    * A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html 
    */ 
    BlockCipher blockCipher = new AESEngine(); 

    /* 
    * Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html): 
    * - ISO10126d2Padding 
    * - ISO7816d4Padding 
    * - PKCS7Padding 
    * - TBCPadding 
    * - X923Padding 
    * - ZeroBytePadding 
    */ 
    BlockCipherPadding blockCipherPadding = new ZeroBytePadding(); 

    BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding); 

    return encrypt(input, bufferedBlockCipher, cipherParameters); 
} 

public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = true; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = false; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException { 
    bufferedBlockCipher.init(forEncryption, cipherParameters); 

    int inputOffset = 0; 
    int inputLength = input.length; 

    int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength); 
    byte[] output = new byte[maximumOutputLength]; 
    int outputOffset = 0; 
    int outputLength = 0; 

    int bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.processBytes(
      input, inputOffset, inputLength, 
      output, outputOffset 
     ); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    if (outputLength == output.length) { 
     return output; 
    } else { 
     byte[] truncatedOutput = new byte[outputLength]; 
     System.arraycopy(
       output, 0, 
       truncatedOutput, 0, 
       outputLength 
      ); 
     return truncatedOutput; 
    } 
} 

編輯:哎呀,我剛剛看了你鏈接到文章。這聽起來像他正在談論甚至比我想象的更高層次的抽象(例如,「發送機密消息」)。恐怕我不太明白他在做什麼。

3

假設你用Java編寫你的應用程序,我建議您不要使用特定的供應商,但您開發Sun的JCE(Java加密擴展)之上的應用程序。這樣做可以使您獨立於任何基礎提供者,即只要您使用廣泛實施的密碼,就可以輕鬆切換提供者。它確實給了你一定程度的抽象,因爲你不必知道實現的所有細節,並且可以保護你使用錯誤的類(例如使用原始加密而沒有適當的填充等)。體面的文檔和代碼示例。

0

JCE不會爲我工作,因爲我們希望256位的實力,不能更改系統上的Java配置允許它。太糟糕了,Bouncy Castle沒有像JCE那樣的高層API。

「但請注意,bouncycastle由兩個庫組成,輕量級加密庫和JCE提供程序接口庫。密鑰大小限制由JCE層強制實施,但您不需要使用此圖層。如果你只需要使用輕量級的加密API直接與你沒有任何限制,不管是或不是安裝了什麼政策文件。」 http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

1

我居然發現,這個示例使用的,而不是256位的默認128位加密我做了一個小的變化:

BlockCipher blockCipher = new AESEngine(); 

現在變成:

BlockCipher blockCipher = new RijndaelEngine(256); 

,並與我的客戶端應用程序C++ AES256加密高(ER)的

2

一個例子-level API在BouncyCastle的將是CMS(Cryptographic Message Syntax)封裝一起工作。它從提供程序本身提供一個單獨的jar(bcmail),並寫入JCE(但是,C#版本是針對輕量級API編寫的)。

「發送機密消息」大致上是由CMSEnvelopedDataGenerator類實現的,您真正需要做的就是給它發送消息,選擇加密算法(所有內部處理的細節),然後指定一個或接收者能夠讀取消息的更多方式:這可以基於公鑰/證書,共享密鑰,密碼甚至密鑰協議協議。您可以在郵件中擁有多個收件人,並且可以混合並匹配收件人的類型。

您可以使用CMSSignedDataGenerator類似地發送可驗證的消息。如果你想簽名和加密,CMS結構是可嵌套/可組合的(但順序可能很重要)。還有CMSCompressedDataGenerator和最近添加的CMSAuthenticatedData。