我可以使用标准 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
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