为什么用充气城堡解密后会附加这些方形符号?
Why are these square symbols appended after decrypting with bouncy castle?
我创建了一个简单的 java 方法,它使用充气城堡库加密和解密文本。加密按预期工作,但当我解密某些内容时,我在最后得到这些额外的方形符号:
我认为这可能与填充有关,但我已经关注了 bouncy castle 网站上的 the example,所以我真的不明白为什么我会得到这种输出。这是我正在使用的代码:
[主要]
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);
}
[加密解码器]
// 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);
}
}
请记住,我仍在学习密码学,很想听听任何关于为什么会发生这种情况的解释。提前致谢。
在解密过程中 cipher.getOutputSize(dataBytes.length)
不知道它将从填充中删除多少字节(它甚至不知道你告诉它数据的最后一部分)。所以它告诉你可能的最大值。
因此,您的目标数组比需要的要大,您需要考虑填充了多少数据。
你怎么知道填了多少?从 doFinal
捕获 return 值。那你用它做什么?告诉 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 字节数据将无法成功解密的错误。
我创建了一个简单的 java 方法,它使用充气城堡库加密和解密文本。加密按预期工作,但当我解密某些内容时,我在最后得到这些额外的方形符号:
我认为这可能与填充有关,但我已经关注了 bouncy castle 网站上的 the example,所以我真的不明白为什么我会得到这种输出。这是我正在使用的代码:
[主要]
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);
}
[加密解码器]
// 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);
}
}
请记住,我仍在学习密码学,很想听听任何关于为什么会发生这种情况的解释。提前致谢。
在解密过程中 cipher.getOutputSize(dataBytes.length)
不知道它将从填充中删除多少字节(它甚至不知道你告诉它数据的最后一部分)。所以它告诉你可能的最大值。
因此,您的目标数组比需要的要大,您需要考虑填充了多少数据。
你怎么知道填了多少?从 doFinal
捕获 return 值。那你用它做什么?告诉 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 字节数据将无法成功解密的错误。