【发布时间】:2019-11-25 18:00:41
【问题描述】:
我一直在使用基本的 Java AES 东西进行一些学习/实验,但我不知道我做错了什么。根据文档, doFinal() 应该一次性加密/解密所有内容,而且它似乎确实这样做了;但是,在解密时,使用无效的 IV,我仍然可以解密 大部分 数据。为了安全起见,请告诉我我的测试代码到底哪里搞砸了?
注意:我没有使用 BC 或 Java Unlimited Strength Crypto Extensions。此代码遵循来自The Oracle JCA Reference Guide 的示例和指导。在下面的代码中,我选择带有 CFB 的 AES(与 CBC 的结果相同),生成密钥,生成 IV,输入 encrypt,核对 IV,然后输入 decrypt,理想情况下(如果我正确理解 CBC 和 CFB),nuked IV 应该将解密的输出渲染为垃圾。但它没有……至少,在我的安装中没有……
还应注意 GCM 确实可以正常工作(您无疑会看到下面注释掉的算法字符串),但 CBC 和 CFB 的这种行为让我感到困扰。现实检查一下好吗?
public static void encdec() throws Exception {
// let's encrypt something!
String message = "This is a super-secret message. Don't read this message. This message will self-destruct...";
final String symmetricCipherSpec = "AES/CFB/PKCS5Padding";// "AES/GCM/NoPadding";
final String symmetricKeySpec = "AES";
System.out.println("\n\nSelecting plaintext cypher...");
Cipher cipher = Cipher.getInstance(symmetricCipherSpec);
// What did we get?
System.out.println("--> Cipher Algorithm Selected: " + cipher.getAlgorithm());
AlgorithmParameters parameters = cipher.getParameters();
System.out.println("--> Parameters for algo: " + parameters.getAlgorithm());
System.out.println("--> block size: " + cipher.getBlockSize());
final int blockSize = cipher.getBlockSize();
KeyGenerator keyGenerator = KeyGenerator.getInstance(symmetricKeySpec);
keyGenerator.init(128);
Key key = keyGenerator.generateKey();
System.out.println("\nsymmetric key = " + Hex.encodeHexString(key.getEncoded()));
// set up for encryption
int tLen = 16;
byte[] basicIV = new byte[tLen];
for (int i = 0; i < basicIV.length; i++) {
basicIV[i] = (byte) i;
}
byte[] messageToEncrypt = message.getBytes();
IvParameterSpec ivSpec = new IvParameterSpec(basicIV);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encryptedMessage = cipher.doFinal(messageToEncrypt);
System.out.println("\nencrypted = " + Hex.encodeHexString(encryptedMessage));
byte[] iv = cipher.getIV();
System.out.println("iv = " + Hex.encodeHexString(iv) + " (len=" + iv.length + ")");
// reset IV to garbage.
basicIV = new byte[tLen];
ivSpec = new IvParameterSpec(basicIV);
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = cipher.doFinal(encryptedMessage);
System.out.println("\ndecrypted = " + new String(decrypted));
System.out.println("original = " + message);
System.out.println("iv = " + Hex.encodeHexString(cipher.getIV()) + " (len=" + cipher.getIV().length + ")");
}
【问题讨论】:
-
大部分是欺骗stackoverflow.com/questions/16349441/…,我相信但没有找到更多,因为这不是一个真正的编程问题交叉欺骗crypto.stackexchange.com/questions/2865/…crypto.stackexchange.com/questions/1129/…它所属的地方。自 2 年前的 8u161 以来,JCE 的“无限”政策也已过时,在此之前并没有影响 128 位。