问题描述
以下是在Java中使用AES加密的摘录:
The following is an extract from using AES encryption in Java:
encryptedData = encryptCipher.doFinal(strToEncrypt.getBytes());
以下是c#中的摘录
DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);
两者都使用一个字节数组来加密另一个解密,Java加密中的加密产生一些负数值存储在字节数组中。
Both use a byte array one to encrypt the other to decrypt, the encryption in Java encrypts producing some negative values stored in a byte array.
C#使用字节数组进行解密,但C#中的字节被定义为仅包含0..255之内的数字-Java定义了它的值字节类型为-128到127。
C# uses a byte array to decrypt but a byte in C# is defined as only containing the numbers from 0..255 - Java defines its Byte type as -128 to 127.
因此,我无法将加密的数据发送到用C#编写的远程应用程序,因为它无法使用已经使用过的字节数组进行解密
Therefore, I cannot send encrypted data to the remote application which is written in C# because it cannot decrypt using the byte array that has been sent from the Java aplication.
有人能提出一种解决方案,让我告诉Java加密时不产生负数吗?
Has anyone come up with a solution that would allow me to tell java not to produce negative numbers when encrypting?
代码来自Micrsoft,MemoryStream要求byte []为加密代码创建流...
如前所述,我用sbyte替换了byte [],但是无用,因为MemoryStream需要byte []
The code is from Micrsoft, the MemoryStream requires the byte[] to create the stream for the crypto code...As mentioned or not, I replaced byte[] with sbyte but to no avail as MemoryStream requires byte[]
static string DecryptStringFromBytes_Aes(sbyte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream((byte)cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
推荐答案
Java的字节是有符号的,C#的字节是无符号的(C#中还有一个 sbyte
类型,没有人使用过,类似于Java的字节)。
Java's bytes are signed, C# bytes are unsigned (there's also an sbyte
type in C#, that no one uses, which works like Java's bytes).
没关系。它们在某些方面有所不同,即
It doesn't matter. They are different in some regards, namely
- 当转换为
int
时,C#的字节将被零扩展,Java的字节将被符号扩展(这就是为什么在Java中使用字节时几乎总是看到& 0xFF
的原因)。 - 当转换为字符串时,Java的字节将其128-255的范围映射到-128--1。只需忽略它即可。
- when converted to
int
, C#'s bytes will be zero-extended, Java's bytes will be sign-extended (which is why you almost always see& 0xFF
when bytes are used in Java). - when converted to string, Java's bytes will have their 128 - 255 range mapped to -128 - -1. Just ignore that.
这些字节的实际值(即它们的位模式)才是真正重要的,一个字节无论您将其解释为170(如C#)还是-86(如Java),0xAA均为0xAA。这是同一件事,只是将其打印为字符串的方式不同。
The actual value of those bytes (that is, their bit-pattern) is what actually matters, a byte that is 0xAA will be 0xAA regardless of whether you interpret it as 170 (as in C#) or -86 (as in Java). It's the same thing, just a different way to print it as string.
new MemoryStream( (byte)cipherText))
绝对不能做正确的事情(或其他任何事情,甚至都不应编译)。相关的 new MemoryStream((byte [])cipherText))
也不起作用,您不能在这样的原始数组之间进行转换。 cipherText
应该只是一个 byte []
开头。
new MemoryStream((byte)cipherText))
definitely doesn't do the right thing (or anything, it shouldn't even compile). The related new MemoryStream((byte[])cipherText))
wouldn't work either, you can't cast between primitive arrays like that. cipherText
should just be a byte[]
to begin with.
这篇关于AES负字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!