我可以使用标准 Java 密码 API 的 BouncyCastle 可调整块密码吗?

Can I use BouncyCastle's Tweakable Block Ciphers using the standard Java Cipher API?

BouncyCastle 提供了 Threefish 的实现,可以将 tweak 作为参数:

ThreeFishEngine engine = new ThreeFishEngine(256);
engine.init(true, new TweakableBlockCipherParams(...));

但是,TweakableBlockCipherParams 与 Java 的默认 Cipher.

实例使用的 AlgorithmParameter 类型不兼容

有没有办法通过调整来初始化此密码?

Cipher cipher = Cipher.getInstance("Threefish-256/CBC/NoPadding");
cipher.init(???);

如果您不想使用 tweak 加密期间的参数。通过Java的API只能引入一个key和一个initialization vector参数,但是这个不会用作调整参数(我在代码示例后解释了原因,请参见下文)。

此外,为了使下面的示例正常工作,您必须使用 Java 加密扩展 (JCE) 无限强度管辖策略文件更新您的 JRE/JDK,您可以从 here 下载该文件. Java 7 和 8 有不同的版本。

如果您不想使用调整参数,您可以像这样通过标准加密 API 使用 Threefish 算法。

static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();

public static void main(String[] args) throws Exception {
    KeyGenerator kg = KeyGenerator.getInstance("Threefish-1024", PROVIDER);
    kg.init(1024);
    SecretKey key = kg.generateKey();

    byte[] plaintext = "Hi! I'm cat!".getBytes();
    byte[] ciphertext = encrypt(key, plaintext);
    System.out.println(new String(decrypt(key, ciphertext)));
    // prints "Hi! I'm cat!"
}

static byte[] encrypt(SecretKey key, byte[] plaintext) throws Exception {
    return encryptOrDecrypt(true, key, plaintext);
}

static byte[] decrypt(SecretKey key, byte[] ciphertext) throws Exception {
    return encryptOrDecrypt(false, key, ciphertext);
}

static byte[] encryptOrDecrypt(boolean encrypt, SecretKey key, byte[] bytes) throws Exception {
    Cipher cipher = Cipher.getInstance("Threefish-1024/CBC/PKCS5Padding", PROVIDER);
    // note that we are creating a dummy iv parameter, in this case it
    // should be 128 bytes long, because if it's not an exception is raised
    cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[128]));
    return cipher.doFinal(bytes);
}

我下载了一个带有调试符号 from here and debugged the above code. The call to Cipher.init lands in Threefish.init 的 Bouncy Castle JAR,变量 params 将是 KeyParameter 的一个实例,而不是 TweakableBlockCipherParameters 在我们的例子中。因此,tweakBytes 将为空,不会在加密期间使用。

知道这一点,现在不可能使用 Java API 向底层 Threefish 密码引擎提供调整参数。

Link to another very similar question