AES负字节

时间:2014-04-15 09:01:55

标签: c# java aes

以下是在Java中使用AES加密的摘录:

  encryptedData =   encryptCipher.doFinal(strToEncrypt.getBytes());

以下是c#

中的摘录
 DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);

两者都使用字节数组1加密另一个进行解密,Java中的加密加密产生一些存储在字节数组中的负值。

C#使用字节数组进行解密,但C#中的字节定义为仅包含0..255中的数字 - Java将其字节类型定义为-128到127.

因此,我无法将加密数据发送到用C#编写的远程应用程序,因为它无法使用从Java应用程序发送的字节数组进行解密。

有没有人提出一个解决方案,允许我告诉java在加密时不要产生负数?

代码来自Micrsoft,MemoryStream要求byte []为加密代码创建流... 无论提到与否,我用sbyte替换了byte []但无效,因为MemoryStream需要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;


    }

2 个答案:

答案 0 :(得分:1)

Java的字节是有符号的,C#字节是无符号的(C#中也有sbyte类型,没有人使用,类似于Java的字节。)

没关系。它们在某些方面有所不同,即

  • 转换为int时,C#的字节将被零扩展,Java的字节将被符号扩展(这就是为什么在Java中使用字节时几乎总是看到& 0xFF。)
  • 转换为字符串时,Java的字节将其128 - 255范围映射到-128 - -1。请忽略它。

这些字节的实际值(即它们的位模式)实际上是重要的,0xAA的字节将是0xAA,无论您将其解释为170(如在C#中)还是-86(如在使用Java)。这是同样的事情,只是一种不同的方式将其打印为字符串。


new MemoryStream((byte)cipherText))肯定不会做正确的事(或任何事情,它甚至不应该编译)。相关的new MemoryStream((byte[])cipherText))也不起作用,你不能在这样的原始数组之间进行转换。 <{1}}应该只是一个cipherText

答案 1 :(得分:0)

您可以将其转换为具有某些编码的字符串,例如:

encryptedData =   encryptCipher.doFinal(strToEncrypt.getBytes());
String s = new String(encryptedData, "Base-64");

使用相同的标准化编码,C#和Java都应该能够从该字符串重建彼此的加密数据。