27

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

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

第二个服务查找有关该用户的信息,然后将其传递回第 3 方服务。

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

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

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

4

7 回答 7

12

高级抽象?我想 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;
    }
}

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

于 2009-05-20T12:07:43.827 回答
3

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

于 2009-05-20T22:15:57.983 回答
2

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

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

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

于 2010-02-02T13:39:14.200 回答
1

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

BlockCipher blockCipher = new AESEngine();

现在变成:

BlockCipher blockCipher = new RijndaelEngine(256);

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

于 2009-10-13T00:42:57.817 回答
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

于 2012-10-26T08:20:17.700 回答
0

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

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

于 2009-08-07T16:38:20.910 回答
0

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

于 2009-08-20T13:46:32.333 回答