代码之家  ›  专栏  ›  技术社区  ›  Jeff Martin

我该如何开始使用BouncyCastle?[关闭]

  •  25
  • Jeff Martin  · 技术社区  · 15 年前

    所以之后 CodingHorror's fun with encryption 以及令人头疼的评论,我们正在重新考虑做我们自己的加密。

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

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

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

    在编写恐怖代码的文章中,CodaHale推荐使用BouncyCastle和库中的高级抽象来进行特定需求的加密。

    我的问题是bouncycastle名称空间很大,文档不存在。有人能给我指一下这个高级抽象库吗?(或者除了弹性柱之外的另一种选择?)

    7 回复  |  直到 8 年前
        1
  •  11
  •   Adam Paynter    15 年前

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

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

        2
  •  3
  •   Accipitridae    15 年前

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

        3
  •  2
  •   user    8 年前

    BouncyCastle中高(ER)级别API的一个示例是CMS( Cryptographic Message Syntax )包装。这将从提供者本身发送到一个单独的JAR(bcmail)中,并写入JCE(但是,C版本是针对轻量级API编写的)。

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

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

        4
  •  1
  •   LPL user462990    13 年前

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

    BlockCipher blockCipher = new AESEngine();
    

    现在变成:

    BlockCipher blockCipher = new RijndaelEngine(256);
    

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

        5
  •  1
  •   Wernight    12 年前

    您可以使用:

    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
  •  0
  •   Kevin    15 年前

    JCE不能为我工作,因为我们需要256位的强度,并且不能改变系统上的Java配置以允许它。太糟糕了,BouncyCastle没有JCE那样的高级API。

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

        7
  •  0
  •   iffi    15 年前

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