在Java中使用bouncycastle需要将AES 256位密钥“扩展”为10个轮密钥

3
我正在尝试在Java中实现Cryptonight算法(不使用JNI包装器)。早期的一步是将AES 256位密钥“扩展”为10个轮密钥。我似乎无法理解这里的术语。我猜想我不需要从头开始实现该扩展,因为bouncycastle似乎已经实现了AES。但是我无法在他们的代码中或通过Google找到一个特定讲述“扩展”及其完成方法的操作。如果可能的话,我该如何通过调用bouncycastle API部分来实现这一点呢?我并不一定要学习密码学,尽管我欣赏任何细节,我更想了解如何使用现有库来完成此任务,但如果必要,我也愿意手动完成。

1
我不认为这个扩展会在公共API中显示。毕竟,它是内部工作的一部分。不过你可以尝试自己实现它 - Kayaman
我已经不得不深入了解内部结构,以暴露SHA3摘要的内部状态(而不是最终的64字节摘要)。因此,如果必要,我愿意扩展该代码。我只是不确定应该在哪里查找。 - The Shoe Shiner
你不需要11个轮密钥吗? - Kayaman
算法要求我需要10个。不确定AES是否可以扩展到更多。希望在这里能得到一些澄清。 - The Shoe Shiner
2个回答

5

AES-128使用10轮,AES-192使用12轮,AES-256使用14轮。

在BouncyCastle中,它是通过类org.bouncycastle.crypto.engines.AESEngine实现的,方法名为generateWorkingKey()。这不是一个通用的实现:

该方法以以下方式开始:

[...]
int KC = keyLen >>> 2;
ROUNDS = KC + 6;  // This is not always true for the generalized Rijndael that allows larger block sizes
int[][] W = new int[ROUNDS+1][4];   // 4 words in a block
switch (KC) {
  case 4:
[...]
for (int i = 1; i <= 10; ++i)

阅读这段代码,很容易看出如果您的密钥长度为128位,则keyLen值为16(字节),因此KC为4,然后ROUNDS为10(这是循环的上限)。但它是硬编码的。对于其他密钥长度,以同样的方式硬编码在一个包含循环上限为回合数的switch case中。
因此,对于您的Cryptonight实现,使用256位密钥长度但只需要10轮的情况下,BouncyCastle实现中的硬编码值与您的需求不符。因此,您需要分叉BouncyCastle并修改此代码以实现您的目标。

2
明白了。这是我目前所做的。不过还在测试实现过程中。 - The Shoe Shiner

-2

对于 CryptoNight 修改版的 AES,您只需要从 256 位输入密钥生成 10 个轮密钥。您可以使用标准的 AES 密钥扩展并仅获取前 10 个密钥。 这是我的文章,其中包含描述 AES 密钥计划的 CryptoNight 特定 Java 代码示例: http://cryptoexplained.tech/hash-algorithms/aes-key-schedule


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接