BufferedReader.readLine()破坏了二进制文件

时间:2013-01-24 00:39:26

标签: java binary

出于学术目的,我正在使用java和java加密技术开发基于加密的小型应用程序。也就是说,我通常使用C或C ++(这很容易),所以我很抱歉这是一个明显的问题。所以,当我想要解密信息时,问题出现了。问题与使用加密或任何东西没有多大关系,但事实上,正确地检索我的初始化向量。现在我有一个明文文件,其格式为new-line /冒号(是的,这是不安全的,但这是一个学术练习 - 显然关键文件不会在现实世界的明文中)

password:salt:<IV>

其中<IV>是初始化向量。我决定直接以二进制格式写出初始化向量。现在我在这里是我的问题开始的地方。我可以正确地写出数据(使用hexdump验证),但它似乎没有被正确地读回到程序中。例如,考虑计数器值

00 18 C0 98 (decimal: 1622168)

此值已正确写出。但是,当我尝试读取它时,这个值都是错误的。我怀疑这是BufferedReader.readLine()的结果。我只是读取这一行并将其写入另一个文件,然后将该值更改为

BD EF BF BD (decimal: who cares, very wrong...)

但是ASCII值(密码和salt)以及冒号分隔符保持不变。初始化向量二进制文件是所有被加扰的。

我想做的是:

BufferedReader reader = new BufferedReader(new FileReader(f));
String last  = null;
String parse = null;
while((last = reader.readLine()) != null) {
    parse = last;
}
reader.close();
int offset = // A few indexOf() statements to find the positon;
byte[] iv  = parse.substring(offset).getBytes();

此时,iv.length > 16(使用128位AES)已经出错了。所以我不完全确定如何完成这种ASCII二进制混合(也许这是一个糟糕的设计开始)。我的一部分问题是Java中的char != byte,如果我想读一整行(无论如何都使用readLine()),我不能简单地以字节的形式读取所有内容。但是,无论如何要解决这个问题?因为我想要整行,但我也想从这一行中提取二进制文件。

此外,我还尝试过直接转换

for(int i = 0 ; i < 16 ; ++i)
  iv[i] = (byte)parse.charAt(offset + i);

但这也不起作用。其他代码(基于getBytes())正在使用java version "1.6.0_37"在我的个人计算机上运行,​​但部署环境正在使用java version "1.6.0_33",这是失败的。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:10)

什么是二进制数据?您如何知道哪个0x0A是数据?哪个是换行符?

要点BufferedReader用于阅读文本,而不是任意数据!它会将您的所有数据视为文本。它还会尝试使用某种编码将二进制文件转换为文本,这当然会破坏您的数据。

更好的方法是:

  • 不将任何数据写为二进制文件,并依赖换行符或其他分隔符。 (例如继续使用BufferedReader.readLine()
  • 将所有数据写为二进制文件,并将文件中的每条记录设置为固定长度,或者提出一些更复杂的分隔符方案。 (例如,只使用FileInputStream.read(byte[])