【问题标题】:How do I get started using BouncyCastle? [closed]如何开始使用 BouncyCastle? [关闭]
【发布时间】:2009-05-19 23:11:41
【问题描述】:

所以在CodingHorror's fun with encryption 和颠簸的 cmets 之后,我们正在重新考虑进行我们自己的加密。

在这种情况下,我们需要将一些识别用户的信息传递给第三方服务,然后第三方服务将使用这些信息和哈希值回调我们网站上的服务。

第二个服务查找该用户的信息,然后将其传回给第三个服务。

我们想加密这些进入第 3 方服务的用户信息,并在它出来后解密。所以它不是一个长期存在的加密。

在编码恐怖文章中,Coda Hale 推荐了 BouncyCastle 和库中的高级抽象来针对特定需求进行加密。

我的问题是 BouncyCastle 命名空间很大,而且文档不存在。谁能指出我这个高级抽象库? (或者除了 BouncyCastle 之外的其他选择?)

【问题讨论】:

  • 重新考虑编写自己的加密库?不错的选择!
  • 虽然没有很多关于 BouncyCastle 的文档,但我发现他们的邮件列表非常有帮助 bouncycastle.org/csharpdevmailarchive/index.html。您也可以订阅提问。您还应该获得它附带的示例和测试的源代码,涵盖了大多数用例。
  • 您所描述的内容听起来像是 OAuth 的典型用例 - 您是否考虑过使用它?
  • @NickJohnson 虽然当我问这个问题时 OAuth 在技术上已经存在——它没有正式化,当然也没有广为人知。 en.wikipedia.org/wiki/OAuth#History
  • 将此标记为“不具建设性”是……不具建设性。 BouncyCastle 是一堆未记录的界面,对人类观察者来说毫无意义。在这种情况下,寻求一种实用的入门方法是人们可以要求的最具建设性的事情。我理解为什么这个网站有标准,但标准不应该妨碍现实生活。

标签: cryptography bouncycastle


【解决方案1】:

高级抽象?我想 Bouncy Castle 库中的最高级别抽象包括:

我最熟悉该库的 Java 版本。也许这段代码 sn-p 将为您的目的提供足够高的抽象(例如使用 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;
    }
}

编辑:糟糕,我刚刚阅读了您链接到的文章。听起来他在谈论比我想象的更高级别的抽象(例如,“发送机密消息”)。恐怕我不太明白他在说什么。

【讨论】:

  • 感谢您查看这篇文章...如果有一个像他所描述的那样的库会很好,因为加密的用途很多,而且误用更大。
  • 努力+1,但不是我可以使用的答案。
  • Adam Paynter 也看看我的问题。我只是想使用 chcacha20 加密文本。 stackoverflow.com/questions/38050559/…
【解决方案2】:

假设您使用 Java 编写应用程序,我建议您不要使用特定的提供程序,而是在 Sun 的 JCE(Java 密码术扩展)之上开发您的应用程序。这样做可以使您独立于任何底层提供者,即,只要您使用广泛实施的密码,您就可以轻松切换提供者。它确实为您提供了一定程度的抽象,因为您不必了解实现的所有细节,并且可以保护您免于使用错误的类(例如,使用未经适当填充的原始加密等)此外,Sun 提供大量的文档和代码示例。

【讨论】:

    【解决方案3】:

    在 BouncyCastle 中的高级(更)级 API 的一个示例是 CMS (Cryptographic Message Syntax) 包。这与提供者本身放在一个单独的 jar (bcmail) 中,并写入 JCE(但是 C# 版本是针对轻量级 API 编写的)。

    “发送机密消息”大致是由 CMSEnvelopedDataGenerator 类实现的,你真正需要做的就是给它消息,选择一种加密算法(所有细节都在内部处理),然后指定一个或多个接收者能够读取消息的方式:这可以基于公钥/证书、共享秘密、密码,甚至是密钥协商协议。一条消息可以有多个收件人,并且可以混合和匹配收件人类型。

    您可以使用 CMSSignedDataGenerator 类似地发送可验证的消息。如果要签名和加密,CMS 结构是可嵌套/可组合的(但顺序可能很重要)。还有 CMSCompressedDataGenerator 和最近添加的 CMSAuthenticatedData。

    【讨论】:

      【解决方案4】:

      我实际上发现此示例使用默认的 128 位加密而不是 256 位。我做了一点改动:

      BlockCipher blockCipher = new AESEngine();
      

      现在变成:

      BlockCipher blockCipher = new RijndaelEngine(256);
      

      它与我的客户端应用程序 C++ AES256 加密一起使用

      【讨论】:

        【解决方案5】:

        你可以使用:

        byte[] process(bool encrypt, byte[] input, byte[] key)
        {
            var cipher = CipherUtilities.GetCipher("Blowfish");
            cipher.Init(false, new KeyParameter(key));
            return cipher.DoFinal(input);
        }
        
        // Encrypt:
        byte[] encrypted = process(true, clear, key);
        
        // Decrypt:
        byte[] decrypted = process(false, encrypted, key);
        

        见:https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs

        【讨论】:

          【解决方案6】:

          JCE 不适用于我,因为我们需要 256 位强度,并且无法更改系统上的 java 配置以允许它。太糟糕了,Bouncy Castle 没有 JCE 那样高级别的 API。

          "但是请注意,bouncycastle 由两个库组成,轻量级加密库和 JCE 提供者接口库。密钥大小限制由 JCE 层强制执行,但您不需要使用该层。如果您只使用轻量级加密 API 直接没有任何限制,无论安装或未安装什么策略文件。” http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

          【讨论】:

          • 我宁愿放弃 256 位的要求,也不愿放弃使用高级接口的可能性和轻松切换供应商的可能性。我不是 bouncycastle 图书馆的粉丝,因为我的口味有太多缺陷。因此,即使我在开发过程中使用 bouncycastle,我也希望能够在我的代码投入生产后将其切换为更好的东西。在设计加密应用程序时,多功能性是一个重要方面。锁定提供者或一组加密原语可能会对您造成很大伤害。
          【解决方案7】:

          这本书Beginning Cryptography with Java 包含基于 bouncycastle 库的非常有用的示例和解释

          【讨论】:

            猜你喜欢
            • 2013-11-05
            • 2010-09-07
            • 2011-12-03
            • 2011-02-27
            • 2011-11-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-25
            相关资源
            最近更新 更多