我创建了一个简单的java方法,该方法使用有弹性的城堡库对文本进行加密和解密。加密按预期工作,但是当我解密某些内容时,最后得到以下多余的方形符号:
我认为这可能与填充有关,但是我一直遵循the example在Bouncy Castle网站上的推荐,所以我真的不明白为什么我会得到这种输出。这是我正在使用的代码:
[主要]
public static void main(String[] argv) {
String ciphertext = "PlJR5pzbowsuzHIc9iTKHg==";
String decrypted;
CryptoCodec codec = new CryptoCodec();
decrypted = codec.exec("AES", "xxxxooooxxxxoooo", ciphertext, false);
System.out.println("Ciphertext: " + ciphertext);
System.out.println("Decrypted: " + decrypted);
}
[CryptoCodec]
// Eod: (true) Encrypt or (false) decrypt.
public String exec(String algorithm, String key, String data, boolean eod) {
// Using AESEngine();
BlockCipher engine = CipherEngine.getBlockCipher(algorithm);
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
byte[] dataBytes;
if(eod) {
dataBytes = data.getBytes(StandardCharsets.UTF_8);
} else {
dataBytes = Base64.decode(data);
}
cipher.init(eod, new KeyParameter(keyBytes));
byte[] outputText = new byte[cipher.getOutputSize(dataBytes.length)];
int outputTextLen = cipher.processBytes(dataBytes, 0, dataBytes.length, outputText, 0);
try {
cipher.doFinal(outputText, outputTextLen);
} catch (CryptoException err) {
err.printStackTrace();
}
if(eod) {
return new String(Base64.encode(outputText));
} else {
return new String(outputText);
}
}
请记住,我仍在学习密码学,很想听听任何解释为什么会发生这种情况。预先感谢。
答案 0 :(得分:4)
在解密cipher.getOutputSize(dataBytes.length)
期间,它不知道将从填充中删除多少个字节(甚至不知道您是在告诉数据的最后一部分)。因此,它告诉您可能的最大值。
因此,您的目标数组大于所需的数组,并且您需要注意要填充多少数据。
您怎么知道填写了多少?从doFinal
捕获返回值。那你怎么办呢?告诉String构造函数何时停止阅读。
然后您得到类似
的内容try {
outputTextLen += cipher.doFinal(outputText, outputTextLen);
} catch (CryptoException err) {
err.printStackTrace();
}
if(eod) {
return new String(Base64.encode(outputText));
} else {
return new String(outputText, 0, outputTextLen);
}
这也修复了您的错误,即如果您现在加密16字节的数据将无法成功解密。