出于学术目的,我正在使用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"
,这是失败的。任何帮助表示赞赏。
答案 0 :(得分:10)
什么是二进制数据?您如何知道哪个0x0A
是数据?哪个是换行符?
要点BufferedReader
用于阅读文本,而不是任意数据!它会将您的所有数据视为文本。它还会尝试使用某种编码将二进制文件转换为文本,这当然会破坏您的数据。
更好的方法是:
BufferedReader.readLine()
)FileInputStream.read(byte[])
)