我该怎么做?我有使用Java中的AES / CBC / PKCS5Padding加密文件的代码,据我了解这张图片:
部分解密应该可以使用前一个块和密钥使用的密文的一部分。但是,我没有找到任何这方面的例子。有什么帮助吗?
解密代码如下:
//skip the IV (ivSize is 16 here) - IV was pretended to the stream during encryption
data.skip(ivSize);
//skip n blocks
int n = 2;
System.out.println("skipped: " + data.skip(n*16));
byte[] iv = new byte[ivSize];
//use next 16 bytes as IV
data.read(iv);
// Hashing key.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(encryptionKey.getBytes(StandardCharsets.UTF_8));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
Cipher cipher;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
} catch (GeneralSecurityException e) {
throw new IOException(e);
}
CipherInputStream cis = new CipherInputStream(data, cipher);
try {
ByteStreams.copy(ByteStreams.limit(cis, limit), output);
} catch (IOException exception) {
// starting with java 8 the JVM wraps an IOException around a GeneralSecurityException
// it should be safe to swallow a GeneralSecurityException
if (!(exception.getCause() instanceof GeneralSecurityException)) {
throw exception;
}
log.warning(exception.getMessage());
} finally {
cis.close();
}
答案 0 :(得分:4)
是的,这是可能的。
你需要选择"部分"块边界上的长度是块大小倍数,并使用前一个块作为IV。对于AES,块大小为16字节。
如果"部分"包括最后一个块指定正确的填充,否则在此实例中不指定填充NoPadding
:AES/CBC/NoPadding
。这将消除填充错误。只有最后一个块有/正在填充。
Cipher
必须使用正确的填充选项进行实例化,具体取决于它是否是整个加密数据的最后一个块。
请参阅:PKCS#7 padding(有时称错误的PKCS#5),这是最常见的填充。