1

我目前正在编写一个非常小的 Java 程序来实现一次性填充,其中填充(或密钥)本身使用 SecureRandom 对象生成为一系列字节,该对象使用带有 SHA- 的简单字符串播种512算法。

生成一次性填充没有引起任何问题,如果我每次都提供相同的种子字符串,正如预期的那样,我会得到相同的伪随机数序列,只要解密人有,就可以进行解密过程用于加密的种子字符串。

当我尝试加密文件时,程序一次读取 64 个字符的数据(除了文件末尾,通常是奇数),并生成 64 个字节(或匹配数量)的伪随机字节。在两个数组的元素之间执行 XOR,将生成的包含密码字符的char数组写入文件,并重复该过程,直到读取文件中的所有文本。

现在,因为 Java 将所有原语视为有符号数字(数据类型字节的范围从 -128 到 127,而不是0 到 255),这意味着 XOR 操作可以(并且确实)导致一些负值(-128 到 -1) . 似乎 Java 无法将这些值识别为有效的 ASCII,而只是写了一个 ? (问号)到文件的任何负值。在从文件中读取以解密密文时,导致 ? 要写入文件的内容丢失,替换为 63,即问号的有效 ASCII 码。

这意味着对这个值进行异或是没有用的,没有原始值就无法生成明文。顺便说一句,如果我重现加密某些数据然后立即解密数据的行为,在同一个程序运行中,以及一路打印状态,没有问题。只有将数据写入文件时,信息才会丢失。

我还应该提到,我确实尝试将 128 添加到每个加密 XOR 结果,然后在执行解密 XOR 之前减去它(将每个值放在有效的 ASCII 范围内),但是?问题仍然出现,因为从 128 到 159 的 31 个 ASCII 代码我无法阅读并显示为?

一段时间以来,我一直在努力解决这个问题,感谢您的帮助。干杯。

4

2 回答 2

1

我想问题出在你写文件的方式上。将转换后的字节数组直接写入 FileOutputStream,不要尝试先将其转换为字符串。对于阅读,做同样的事情,将它读入一个字节数组。

于 2010-10-09T22:23:00.410 回答
1

这很困惑。如果您正在处理 char 数组,则元素为 16 位宽,它们是无符号的,并且并非所有值都有效。所以(a)你不可能有符号或字节的问题,并且(b)你根本不应该这样做。您应该将文件读入字节数组,进行异或运算,然后将字节数组直接写入输出文件。没有读者或作家,没有字符,没有字符串。

于 2010-10-10T00:10:42.753 回答