3

出于学术目的,我正在使用 java 和 java crypto 开发一个基于加密的小型应用程序。也就是说,我通常在 C 或 C++ 中工作(这恰好很容易),所以如果这是一个明显的问题,我深表歉意。所以当我想解密信息时,我的问题就来了。这个问题与使用加密或任何东西没有太大关系,但事实上,正确检索我的初始化向量。现在我有一个纯文本文件,格式为换行符/冒号分隔(是的,这是不安全的,但这是一个学术练习——显然密钥文件在现实世界中不会是纯文本的)

password:salt:<IV>

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

00 18 C0 98 (decimal: 1622168)

该值被正确写出。但是,当我尝试读入它时,这个值全错了。我怀疑这是BufferedReader.readLine(). 我只需读取这一行并将其写入另一个文件,然后将该值更改为

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

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

我想做的是:

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"失败的地方。任何帮助表示赞赏。

4

1 回答 1

10

什么是一行二进制数据?你怎么知道哪个0x0A是数据,哪个是换行符?

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

更好的方法是:

  • 不要将任何数据写入二进制文件,并依赖换行符或其他分隔符。(例如继续使用BufferedReader.readLine()
  • 将所有数据写入二进制文件,或者使文件中的每条记录都具有固定长度,或者提出一些更复杂的分隔符方案。(例如,只需使用FileInputStream.read(byte[])
于 2013-01-24T00:49:48.467 回答