如何开始使用 BouncyCastle?

发布于 2024-07-22 11:06:50 字数 470 浏览 2 评论 0原文

因此,在CodingHorror 的加密乐趣和激烈的评论之后,我们正在重新考虑做我们自己的加密。

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

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

我们希望对进入第三方服务的用户信息进行加密,并在其出来后对其进行解密。 所以它不是一个长期存在的加密。

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

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

So after CodingHorror's fun with encryption and the thrashing comments, we are reconsidering doing our own encryption.

In this case, we need to pass some information that identifies a user to a 3rd party service which will then call back to a service on our website with the information plus a hash.

The 2nd service looks up info on that user and then passes it back to the 3rd party service.

We want to encrypt this user information going into the 3rd party service and decrypt it after it comes out. So it is not a long lived encryption.

On the coding horror article, Coda Hale recommended BouncyCastle and a high level abstraction in the library to do the encryption specific to a particular need.

My problem is that the BouncyCastle namespaces are huge and the documentation is non-existant. Can anyone point me to this high level abstraction library? (Or another option besides BouncyCastle?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

奢华的一滴泪 2024-07-29 11:06:50

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

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

编辑:哎呀,我刚刚阅读了您链接到的文章。 听起来他正在谈论比我想象的更高层次的抽象(例如,“发送机密消息”)。 恐怕我不太明白他的意思。

High level abstraction? I suppose the highest level abstractions in the Bouncy Castle library would include:

I am mostly familiar with the Java version of the library. Perhaps this code snippet will offer you a high enough abstraction for your purposes (example is using AES-256 encryption):

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;
    }
}

Edit: Whoops, I just read the article you linked to. It sounds like he is talking about even higher level abstractions than I thought (e.g., "send a confidential message"). I am afraid I don't quite understand what he is getting at.

盗梦空间 2024-07-29 11:06:50

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

Assuming that you write your application in Java I'd recommend that you don't use a specific provider, but that you develop your application on top of Sun's JCE (Java Cryptography Extension). Doing so can make you independent of any underlying providers, I.e., you can switch providers easily as long as you use ciphers that are widely implemented. It does give you a certain level of abstraction as you don't have to know all the details of the implementations and may protect you a little from using the wrong classes (e.g. such as using raw encryption without proper padding etc) Furthermore, Sun provides a decent amount of documentation and code samples.

攒一口袋星星 2024-07-29 11:06:50

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

BlockCipher blockCipher = new AESEngine();

现在变成了:

BlockCipher blockCipher = new RijndaelEngine(256);

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

I've actually found that this sample uses default 128 bit encryption instead of 256 bit. I've made a little change:

BlockCipher blockCipher = new AESEngine();

now becomes:

BlockCipher blockCipher = new RijndaelEngine(256);

and it works together with my client application C++ AES256 encryption

傻比既视感 2024-07-29 11:06:50

BouncyCastle 中的高级 API 的一个示例是 CMS(加密消息语法) 包。 这与提供程序本身放在一个单独的 jar (bcmail) 中,并写入 JCE(但是,C# 版本是针对轻量级 API 编写的)。

粗略地说,“发送机密消息”是由 CMSEnvelopedDataGenerator 类实现的,您真正需要做的就是向其提供消息,选择一种加密算法(所有细节均在内部处理),然后指定一种或多种方式来发送机密消息。收件人将能够读取消息:这可以基于公钥/证书、共享秘密、密码,甚至密钥协商协议。 一封邮件中可以有多个收件人,并且可以混合和匹配收件人类型。

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

One example of a high(er)-level API in BouncyCastle would be the CMS (Cryptographic Message Syntax) package. This ships in a separate jar (bcmail) from the provider itself, and is written to the JCE (The C# version is written against the lightweight API however).

"Send a confidential message" is implemented, roughly speaking, by the CMSEnvelopedDataGenerator class, and all you really need to do is give it the message, choose an encryption algorithm (all details handled internally), and then specify one or more ways that a recipient will be able to read the message: this can be based on a public key/certificate, a shared secret, a password, or even a key agreement protocol. You can have more than one recipient on a message, and you can mix and match types of recipient.

You can use CMSSignedDataGenerator to similarly send a verifiable message. If you want to sign and encrypt, the CMS structures are nestable/composable (but order could be important). There's also CMSCompressedDataGenerator and recently added CMSAuthenticatedData.

说好的呢 2024-07-29 11:06:50

您可以使用:

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

You may use:

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);

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

甜嗑 2024-07-29 11:06:50

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

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

JCE won't work for me because we want 256 bit strength and can't change the java configuration on the system to allow it. Too bad the Bouncy Castle doesn't have an API as high-level as JCE.

"Note however that bouncycastle consists of two libraries, the lightweight crypto library and the JCE provider interface library. The keysize restrictions are enforced by the JCE layer, but you don't need to use this layer. If you just use the lightweight crypto API directly you don't have any restrictions, no matter what policy files are or are not installed."
http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

清风不识月 2024-07-29 11:06:50

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

The book Beginning Cryptography with Java contains very helpful examples and explanations based on the bouncycastle library

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文