【问题标题】:Is AES256 encryption decryption possible in Java without unlimited strength JCE files?在没有无限强度 JCE 文件的情况下,Java 中是否可以进行 AES256 加密解密?
【发布时间】:2017-01-26 08:26:20
【问题描述】:

我正在进行的项目有一个需要 AES 加密和解密的部分。从我可以查找的所有可能的 Internet 资源中,很难找到任何对 AES256 加密的参考,而无需从 Sun(现在是 Oracle 的网站)下载和安装 Unlimited Strength JCE 文件。除了相同的分发存在的任何法律问题之外,当要求最终用户访问特定网站并下载一些文件,将它们放在目录中然后将内容添加到类路径时,它对我们没有多大帮助在 Windows 等上!

互联网上有一些关于 BountyCastle 的轻量级 API 的参考资料,可能不需要 JCE 文件,但我找不到非常相关的参考资料或示例来演示它。

不确定,但这是所有其他编程语言的问题吗?

如果不安装那些特定的 JCE 文件就无法进行 AES 256 位加密,那么 JNI 方法可以提供帮助吗?

详细说明一下,可以在 C/C++ 中完成 AES 256 加密,然后我可以调用那些使用 JNI 来获得所需的结果吗?将软件打包(作为 jar 文件)是否会引起关注,还是会有其他问题?

另一个重要的因素是该项目将在 Mac 和 Windows 上运行,因此使用 C/C++(特定的编译器/解释器版本或任何东西)可能会受到限制吗?

有没有不同的方法来处理这个问题?还有其他方法吗?

【问题讨论】:

  • 欢迎来到Stack Overflow。我冒昧地删除了一些不必要的文本。我们喜欢我们的问题简明扼要,如果没有那段文字,这个问题已经很长了;-)
  • 我想你可以在这里找到一个 Java AES 实现:jce.iaik.tugraz.at 但我认为它只对研究人员/学生免费。
  • 不要忘记投票或接受答案,诺拉...

标签: java encryption java-native-interface aes


【解决方案1】:

密钥大小限制在 Java 的 Cipher 类中实现。可以使用任何实现 AES 的 other 类来获得 AES-256 功能。例如,可以使用Bouncy Castle 的“轻量级”API 来使用任何强度的密钥大小。在这种情况下,您可以例如直接使用org.bouncycastle.crypto.engines.AESFastEngine(以及您选择的modepadding。仍然可以为Bouncy Castle 使用普通的.jar,但您不会使用BouncyCastle 提供程序的JCA 功能。

这有一些缺点和优点。轻量级 Bouncy Castle API 比 "BC" 提供者添加到 Sun 类的 JCA 功能要低一些。此外,许多组件(例如 Java 中的 SSL 层、JSSE 或 XML 加密库)使用 JCA 来提供所需的加密功能。需要 JCA 功能的库仍将受限于密钥大小。

请注意,使用其他提供程序 将不起作用,因为Cipher 类本身会检查密钥大小。可能包含在 JCA 提供程序中的 CipherSpi 实现类不能(积极地)影响允许的密钥大小。只能直接使用实现类。

【讨论】:

    【解决方案2】:

    首先,不是每个编程环境都有问题。例如,用 C 编写的 OpenSSL 支持大密钥。但是,根据 JCE 和 JNI 的经验,我建议您找到一种使用纯 Java 的方法,而不是通过 JNI 加载本机库。就简单多了。

    一个实用的解决方案: 您的应用程序是否在安装过程中使用某种安装程序应用程序安装?如果是这样,那么一种解决方案可能是使用此安装程序来安装 JCE。

    不幸的是,BouncyCastle 也使用 JCE,如其FAQ 所述。

    更新 1: 我找到了这个库,这可能就是你要找的。然而,它似乎不再被维护:http://www.cryptix.org/

    更新 2: GNU 有一个实现 AES256 的库:http://www.gnu.org/software/gnu-crypto/。更多关于可用密码的信息:http://www.gnu.org/software/gnu-crypto/manual/Ciphers.html

    假设您已经在key_bytes 中加载了密钥,则使用 GNU-Crypto 的代码示例:

    IBlockCipher cipher = CipherFactory.getInstance("AES");
    Map attributes = new HashMap();
    attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(16));
    attributes.put(IBlockCipher.KEY_MATERIAL, key_bytes);
    cipher.init(attributes);
    int bs = cipher.currentBlockSize();
    
    for (int i = 0; i + bs < pt.length; i += bs)
    {
        cipher.encryptBlock(pt, i, ct, i);
    }
    
    for (int i = 0; i + bs < cpt.length; i += bs)
    {
        cipher.decryptBlock(ct, i, cpt, i);
    }
    

    请确保您使用加密安全的随机数生成器(例如 SecureRandom)为密钥创建 256 个字节:

    byte[] seed = xxx; // Be sure to get a good new seed on every client machine.
    SecureRandom random = new SecureRandom(seed);
    byte[] key_bytes = new byte[256];
    random.nextBytes(key_bytes);
    

    【讨论】:

    • Bouncycastle 轻量级 API使用 JCE,因此不需要无限管辖加密文件。
    • @GregS 以此作为答案的基础
    • 指向未维护的加密库通常应该以 -1 结尾,但我会保留它,因为其他信息是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2019-10-13
    相关资源
    最近更新 更多