小编典典

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

java

我在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中使用 无符号字节
  • 或其他解决我的问题的方法?

阅读 410

收藏
2020-11-26

共1个答案

小编典典

尽管您不能在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

  1. 使用0xFF00000000 00000000 00000000 11111111通过执行二进制AND运算符可“屏蔽”此值:

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

该值与200带符号整数的值相同。

2020-11-26