- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我们使用以下语句实例化密码:
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec key = new SecretKeySpec(cipherKey, "AES");
这在 Java 7 (1.7_45) 中有效,但在 Java 8 (1.8_25) 中不再有效。我们将 cipher
传递给 CipherInputStream
并使用流来读取/写入数据。实际异常发生在 close
期间。
编辑:
快速查看 JDK 代码会发现 BadPaddingException 被重新抛出,在 7 中它被忽略了:
JDK 7:CipherInputStream.close:
try {
this.cipher.doFinal();
} catch (BadPaddingException var2) {
;
} catch (IllegalBlockSizeException var3) {
;
}
JDK 8:CipherInputStream.close:
try {
if(!this.done) {
this.cipher.doFinal();
}
} catch (IllegalBlockSizeException | BadPaddingException var2) {
if(this.read) {
throw new IOException(var2);
}
}
问题是如何首先避免 BadPaddingException?
编辑 2:
经过一些研究和实验,我们得出了以下测试程序:
public final class CipherSpike2 {
private static final byte[] SECRET_KEY = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
public static void main(String[] args)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IOException {
encryptDecrypt(511);
encryptDecrypt(512);
}
private static void encryptDecrypt(int i)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
byte[] clearText = generateClearText(i);
System.out.println("Clear text length: " + clearText.length);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(bos, getCipher(Cipher.ENCRYPT_MODE));
cos.write(clearText);
cos.close();
final byte[] content = bos.toByteArray();
System.out.println("written bytes: " + content.length);
CipherInputStream
inputStream =
new CipherInputStream(new ByteArrayInputStream(content), getCipher(Cipher.DECRYPT_MODE));
inputStream.read();
inputStream.close();
}
private static byte[] generateClearText(int size) {
return new byte[size];
}
private static Cipher getCipher(int encryptMode)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(SECRET_KEY, "AES");
cipher.init(encryptMode, key);
return cipher;
}
}
首先,程序写入 511 个字节,结果是一个 512 字节长的“文件内容”。我们只读了一个字节。 CipherInputStream 读取 512 字节 block 中的数据,因此每个字节都被读取,我们可以关闭流。
接下来,我们创建一个 512 字节的内容。这被填充为 528。如果我们现在只读取一个字节,我们还剩下一些字节,如果我们现在关闭流,它会崩溃并出现给定的异常。
现在这个问题在与 ZipStreams 结合时尤其成问题:加密内容在前面的步骤中用 ZipOutputStream 压缩并用 ZipInputStream 读取。看起来,ZipInputStream 消耗的字节数与之前写入的字节数不同。
似乎唯一的解决方案是在 close() 中捕获 BadPaddingException。(?)从 API 的角度来看,这对我来说似乎很奇怪,无论我的字节数是多少,我都无法无一异常(exception)地关闭流'已阅读。
编辑 3 ZipStream 阐述:
在我们的应用程序中,我们读取了一堆加密的文本文件。所以流的构造看起来像这样:
BufferedReader/Writer -> InputStreamReader/Writer -> ZipInputStream/Output -> CipherInputStream/Output -> Underlying File Stream
我们使用“传统的”while (reader.readLine != null) 循环读取文件内容,直到到达 EOF。之后我们尝试关闭文件。但有时这会导致 Java 8 出现异常 - 见上文(-:。似乎 ZipOutputStream 写入的字节数比 ZipInputStreams 消耗的字节数更多,但我还没有查看代码。
最佳答案
如果您没有完全使用流,Java 1.8 CipherInputStream
将抛出一个 BadPaddingException
。使用 ZipInputStream
时可能就是这种情况,因为以流方式使用 zip 不需要读取文件末尾的 zip 索引。
我建议将 CipherInputStream
包装在 InputStream
的外观实现中,在委托(delegate) close()
时忽略 BadPaddingException
> 方法。当然,如果您的用例需要对流的内容进行身份验证,或者可能发生某种定时预言机攻击,则不要这样做。
关于Java 7 -> Java 8 : AES Causes exception: "BadPaddingException: Given final block not properly padded" in conjunction with BufferedReader & ZipStreams,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27124931/
假设我有一个表示用户的表:id, name。 该表很大,大约有 1 亿行。用户也有一些属性(property),比方说出生城市。这是可选字段,因此只有一小部分用户(假设只有 5%)提供了它。所以我还有
这个问题在这里已经有了答案: static_assert and class templates (2 个答案) 关闭 4 年前。 给定以下代码 ( https://wandbox.org/perm
我正在尝试在 Java 中实现一个 prolog 解释器。我想弄清楚“,”运算符应该如何工作。我试图实现这样的等效规则: and(A, B) :- A, B. 我正在使用测试用例 c1、c2 和 c3
这个问题在这里已经有了答案: Is there a "previous sibling" selector? (33 个答案) 关闭 6 年前。
我有一个关于将 getline 与 If/Else If 语句一起使用的问题。 目前,我的代码如下所示: int yourAge = 13; cout = 21) {
我正在学习 Ruby 类(class),在运行其中一个示例时遇到错误。这是我的 Ruby 类: require 'json' class User attr_accessor :email, :n
在我的研究中,我自动生成 SMT2,然后将其传递给 Z3。生成的代码基本上是许多不同约束的一个非常大的联合 (and ...)。这样做会失去(或获得?)任何重要的性能,而不是生成许多断言吗? 最佳答案
运行代码直到并包括 plotly_build(p) 和正确的绘图结果。 可重现代码 library(plotly) #data df1 <- data.frame(cond = factor( rep
我有一些过滤器表示为函数 List(MyClass => Boolean) 的列表。我试图获得所有成员的逻辑连接(AND)。我有一种感觉,我可以在这里使用折叠。但我没有得到语法,尤其是关于如何将 My
我正在构建一个移动导航菜单,并将一个图标应用于包含子项(下拉箭头)的 li 元素。我正在使用 :after 伪选择器应用图标。问题是,当我使用 slideToggle 打开/关闭菜单时,箭头图标会在菜
是否存在您无法正确使用 std::conjunction/std::disjunction 并且不使用更“基本”(即语言功能而不是库功能)折叠表达式 &&/||? 例子: // func is ena
我们有一个大 flask_restplus已使用一年左右的应用程序。我们现在想使用 flask_swagger_ui在此应用程序中工作,为应用程序的一部分提供一些静态生成的 swagger 文档。 我
我有以下实体类(从 PersistentObjectSupport 类继承的 ID): @Entity public class AmbulanceDeactivation extends Persi
我想用包含连接表的 Student 查询一个主题。 这种关系是多对多的。我想要连接表 id ( StudentSubject ) 但返回结果为空 Subject.findOne({
尝试使用如下子查询在Hive中运行此查询: select y,m,d,h from A where d not in (select d from B) 我收到一个错误"only subquery e
我目前正在使用 Symfony 2.1.0 开发网络应用程序。 我已经通读了 Templating chapter这本书的一部分,我正在尝试在我的网页中包含 Assets (现在,它只是一个样式表)。
我正在尝试在 Angular 4 应用程序中创建 D3 力导向图 ( https://github.com/d3/d3/blob/master/API.md#forces-d3-force )。 它可
这台机器安装了多个版本的 Java JDK 和多个版本的多个 IDE(Netbeans、IntelliJ、Eclipse 等)最近,我添加了 JDK 15.0.2 和 Netbeans 12.2。尝试
我正在从Spring 3.0.5迁移到3.1,因为我需要自定义RequestMappingHandlerMapping。我在扩展RequestMappingHandlerMapping的插件中遇到问题
make[1]: Entering directory `/tmp/Rtmpvk6s18/R.INSTALL65f35ee3733f/rJava/jri' make -C src JRI.jar ma
我是一名优秀的程序员,十分优秀!