2

我有一个 C# 应用程序,它使用 RijndaelManaged 加密我的部分文件(因为它们是大文件)。所以我将我的文件转换为字节数组并只加密其中的一部分。

然后我想使用Java解密文件。所以我只需要解密在 C# 中加密的文件的一部分(意味着那些字节)。

问题来了。因为在 C# 中我们有无符号字节,而在 Java 中我们有有符号字节。所以我的加密和解密没有按照我想要的方式工作。

在 C# 中,我将加密字节和普通字节连接在一起,并用File.WriteAllBytes. 所以我不能在这里使用sbyte或者我不知道该怎么做:

byte[] myEncryptedFile = new byte[myFile.Length];
for (long i = 0; i < encryptedBlockBytes.Length; i++)
{
   myEncryptedFile[i] = encryptedBlockBytes[i];
}
for (long i = encryptedBlockBytes.Length; i < myFile.Length; i++)
{
   myEncryptedFile[i] = myFileBytes[i];

}

File.WriteAllBytes(@"C:\enc_file.big", myEncryptedFile);

(并且在 Java 中有完全相同的解密代码)

所以我的问题是:

  • C#中有WriteAllsBytes吗?
  • 或者我可以在 Java 中使用无符号字节吗?
  • 或者我的问题的任何其他解决方案?
4

1 回答 1

5

尽管您不能在 Java 中使用无符号字节,但您可以简单地忽略这个问题。

AES - 以及所有现代对称密码 - 对字节进行操作,输入和输出已被定义为字节(或八位字节)。输入和输出已由 NIST 标准化,并且可以使用测试向量。

如果您查看字节的单独位内容,那么{200,201,202}在 C# 和{(byte)200, (byte)201, (byte)202}Java 中是相同的。这是因为 Java 使用字节的二补码表示。

将数字200作为整数:这将是11010000二进制的,-56如果在两个补码的(有符号)字节中使用,则表示 Java 中的数字。现在对称密码将简单地将这些位转换为另一个(通常使用完整的位)。

检索到答案后,当您查看单独的位时,您会发现它们在 C# 和 Java 中是相同的。然而,C# 会将它们解释为无符号值,而 Java 将解释为有符号值。

如果您想在 Java 中打印或使用这些值作为有符号数字,则必须将它们转换为正符号整数。做到这一点的方法是使用int p = b & 0xFF.

这将执行以下操作(我将再次使用数字 200):

  1. (负)字节值扩展为有符号整数,记住符号位:

    11010000变成11111111 11111111 11111111 11010000

  2. 0xFF使用或00000000 00000000 00000000 11111111通过执行二元 AND 运算符来“屏蔽”该值:

    11111111 11111111 11111111 11010000 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 11010000

此值与200作为有符号整数的值相同。

于 2013-07-21T15:36:29.837 回答