11

我正在处理的项目有一个需要 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++(特定的编译器/解释器版本或任何东西)可能会受到限制吗?

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

4

2 回答 2

6

密钥大小限制在CipherJava 类中实现。可以使用任何其他实现 AES 的类来获得 AES-256 功能。例如,可以使用Bouncy Castle的“轻量级”API来使用任何强度的密钥大小。在这种情况下,您可以org.bouncycastle.crypto.engines.AESFastEngine直接使用(以及您选择的模式填充。仍然可以使用.jarBouncy Castle 的法线,但您不会使用 BouncyCastle 提供程序的 JCA 功能。

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

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

于 2013-03-23T15:39:31.713 回答
5

首先,不,每个编程环境都不是问题。例如,用 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

使用 GNU-Crypto 的代码示例,假设您已经将密钥加载到key_bytes

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);
于 2013-03-21T15:24:34.820 回答