我如何开始使用BouncyCastle?

时间:2009-05-19 23:11:41

标签: cryptography bouncycastle

因此,在CodingHorror's fun with encryption和抨击评论之后,我们正在重新考虑进行自己的加密。

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

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

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

在编码恐怖文章中,Coda Hale建议使用BouncyCastle和库中的高级抽象来进行特定需求的加密。

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

7 个答案:

答案 0 :(得分:12)

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

我最熟悉Java的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;
    }
}

编辑:哎呀,我刚看了你链接的文章。听起来他说的是比我想象的更高级别的抽象(例如,“发送机密信息”)。我担心我不太了解他的目标。

答案 1 :(得分:3)

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

答案 2 :(得分:2)

BouncyCastle中高(呃)级API的一个例子是CMS(Cryptographic Message Syntax)包。它从提供程序本身发送到一个单独的jar(bcmail)中,并写入JCE(但是C#版本是针对轻量级API编写的)。

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

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

答案 3 :(得分:1)

您可以使用:

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

答案 4 :(得分:1)

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

BlockCipher blockCipher = new AESEngine();

现在变为:

BlockCipher blockCipher = new RijndaelEngine(256);

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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