【问题标题】:AES 256 (instead of 128) with BouncyCastle带有 BouncyCastle 的 AES 256(而不是 128)
【发布时间】:2012-09-24 21:28:06
【问题描述】:

我遵循this post 的大部分内容,目的是在我的软件中实现 aes 256 加密,它工作得很好

这里的关键点是上面链接中描述的整个实现都使用了AESEngine 类。查看类代码和javadoc reference,AESEngine 是 128 位而不是 256 位分组密码

通过代码和文档搜索,我找不到 192 位或 256 位的实现。他们在哪里?

为了完整起见,这是我实际加密类的核心:

    private void init(String passphrase) {
        try {
            String algorithm = "PBEWithSHA256And256BitAES-CBC-BC"; 

            encryptCipher = createCipher();
            decryptCipher = createCipher();    

            randomGenerator = new RandomGenerator();

            PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), KEY_SALT, ITERATIONS);    

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
            key = keyFactory.generateSecret(keySpec);    

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException occured while trying to generate the crypto key. This error should never occur, check the application code", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("InvalidKeySpecException occured while trying to generate the crypto key. This error should never occur, check the application code", e);
        }
    }    

    private BufferedBlockCipher createCipher() {
        return new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()), new PKCS7Padding());
    }    

    public byte[] encrypt(byte[] data) {
        if (data == null)
            throw new NullPointerException("Cannot encrypt null data");    

        byte[] iv = randomGenerator.generateRandom(IV_SIZE);    

        byte[] encrypted;

        synchronized (encryptCipher) {
            encrypted = runCipher(encryptCipher, true, data, iv);
        }    

        return DataUtil.append(iv, encrypted);
    }    

    public byte[] decrypt(byte[] data) {
        if (data == null)
            throw new NullPointerException("Cannot decrypt null data");    

        byte[] iv = DataUtil.extract(data, 0, IV_SIZE);
        byte[] cipherText = DataUtil.extract(data, IV_SIZE, data.length - IV_SIZE);

        byte[] decrypted;    

        synchronized (decryptCipher) {
            decrypted = runCipher(decryptCipher, false, cipherText, iv);
        }

        return decrypted;
    }

    private byte[] runCipher(BufferedBlockCipher cipher, boolean forEncryption, byte[] data, byte[] iv) {
        String operation = forEncryption ? "encrypt" : "decrypt";

        try {
            KeyParameter keyParam = new KeyParameter(key.getEncoded());
            ParametersWithIV cipherParams = new ParametersWithIV(keyParam, iv);

            cipher.init(forEncryption, cipherParams);

            byte[] result = new byte[cipher.getOutputSize(data.length)];
            int len = cipher.processBytes(data, 0, data.length, result, 0);
            len += cipher.doFinal(result, len);

            //Remove padding se estiver decriptografando
            if(!forEncryption)
                result = DataUtil.extract(result, 0, len);

            return result;
        } catch (DataLengthException e) {
            throw new RuntimeException("DataLengthException occured while trying to " + operation + " data with length " + data.length + ". This error should never occur, check the application code", e);
        } catch (IllegalStateException e) {
            throw new RuntimeException("IllegalStateException occured while trying to " + operation + " data with length " + data.length + ". This error should never occur, check the application code", e);
        } catch (InvalidCipherTextException e) {
            throw new IllegalArgumentException("InvalidCipherTextException occured while trying to " + operation + " data with length " + data.length, e);
        }
    }

【问题讨论】:

  • 只有 128 位块大小的 AES 版本。底层算法 Rijndael 有更高位版本。 AES-256 中的 256 是算法的密钥大小,尽管它对内部向量和轮数也有影响。
  • PS 我假设您使用 Bouncy 来获得 256 位 AES,否则您不需要使用 Bouncy Castle 的轻量级 API。作为一个小的优化,您可以使用 BlockCipher.getBlockSize() 而不是 IV 大小的常量。
  • 假设 owlstead 对您的真正目标是正确的(即使用 256 位 key),请问您是否必须实现这么多这个过程从头开始?只是想仔细检查一下这是一个有趣的非工作时间项目或学校作业。否则,我们可以向您展示更多更容易实现目标的途径。
  • @DuncanJones 这不是学校项目或非工作时间项目。我实际上正在构建一个 java 加密库,以促进和保证在我工作的公司中安全地使用加密。请告诉我你提到的更容易的路线。谢谢
  • @Polaco 对不起,请忽略我。我误读了你在做什么,并认为有一条更快的路线。我现在就溜走……

标签: java cryptography aes bouncycastle


【解决方案1】:

如果您想使用 256 位块大小进行类似 AES 的加密,您应该使用:

http://www.docjar.org/docs/api/org/bouncycastle/crypto/engines/RijndaelEngine.html

但这可能不是你想要的; AES-256 中的 256 大约是密钥大小。然后,底层 128 位 AES 分组密码将使用此密钥大小。 AES 是 Rijndael 的标准化 128 位块版本。

【讨论】:

    【解决方案2】:

    AES 支持 3 种密钥大小 - WikipediaNIST

    您可能指的是固定为 128 位的块大小。

    另外,我尝试浏览代码,它是假设不同的密钥大小 - 128、192 和 256 编写的。复制 - 从代码粘贴 - “AES 指定了 128 位的固定块大小和密钥大小 128/192/256位。这段代码是在假设这些是唯一可能的值的情况下编写的”

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      • 2011-05-23
      • 2015-04-10
      • 1970-01-01
      相关资源
      最近更新 更多