C# 无符号字节加密到 Java 有符号字节解密

Sab*_*eti 2 c# java unsigned signed cryptography

我在 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);
Run Code Online (Sandbox Code Playgroud)

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

所以我的问题是:

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

Maa*_*wes 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. 此值通过执行二元 AND 运算符0xFF00000000 00000000 00000000 11111111通过执行二元 AND 运算符来“屏蔽” :

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

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