使用Java解密代码截断C#加密数据

时间:2017-10-22 00:04:33

标签: java c# xml encryption cryptography

全部,我将一些加密的xml数据(使用AES-128)发布到另一个使用Java解密的应用程序。当Java代码解密xml时,xml的开始标记被截断并且验证失败。我不知道。我可以访问他们的代码库。我可以使用C#解密相同的数据而不会丢失任何数据。请参阅我用来加密和解密数据的代码。我已经研究了这个并且根据研究,我在加密逻辑中将CryushFinalBlocks()和Close()添加到CryptoStream,但这似乎并没有解决问题。

加密代码:

public static string Aes128Encrypt(string plainText)
        {
            string encodedPayload = null;
            string base64Iv = null;
            string base64Key = null;
            byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);  
            using (RijndaelManaged aesAlg = new RijndaelManaged())
            {
                aesAlg.KeySize = 128;
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.BlockSize = 128;            
                base64Iv = Convert.ToBase64String(aesAlg.IV);
                base64Key = Convert.ToBase64String(aesAlg.Key);
                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {                       
                        csEncrypt.Write(plainBytes, 0, plainBytes.Length);
                        csEncrypt.FlushFinalBlock();                        
                        encodedPayload  = Convert.ToBase64String(msEncrypt.ToArray());
                        csEncrypt.Close();
                    }
                    msEncrypt.Flush();
                    msEncrypt.Close();
                }
            }
            return encodedPayload  ;
        }

解密代码:

public static string Aes128Decrypt(string base64Key, string base64IV, string encodedPayload)
        {
            string plainText = null;
            byte[] key = Convert.FromBase64String(base64Key);
            byte[] iv = Convert.FromBase64String(base64IV);
            byte[] encryptedBytes = Convert.FromBase64String(encodedPayload);
            using (RijndaelManaged aesAlg = new RijndaelManaged())
            {
                aesAlg.KeySize = 128;
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.BlockSize = 128;                
                aesAlg.Padding = PaddingMode.PKCS7;
                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(encryptedBytes))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plainText = srDecrypt.ReadToEnd();
                        }                        
                    }

                }
            }

            return plainText;


        }

测试代码:

string textXml = @"<person>
                                    <firstName>Rennish</firstName>
                                    <lastName>Joseph</lastName>
                                    <accountNumber>12345678910</accountNumber>
                                    <ssn>123456</ssn>
                                    </person>";
                Aes128Encrypt(textXml);
                string encodedPayload = "4p6uU7SiqB0uCzsrWXMOStP02HM7mKA6QVzcKoNdu3w1+MYLjYVbW/Ig3XPKRRafeu+WKDMuKJJaEREkrZt/Ycvc50wfe2naJ9d0UT5B7Fre1gIsNfZUIK3SF304+WF8zX730mVsluJABKT3JCkk9AkOGCQWPYzcZvH9dojIqGP7V+2j1+IMOPMWWFIitkAi8B7ALxMuMcepzX2/cxHxH7NeID0ytEGUzGfJXSAzQcvBX9dWwUqdMX3Eip5SRPMsotnWWsFTjDuOiZk/q5fuxxWbS6cuYn/64C/vQjEIuheQKn0ZOIDLNPCUavvWD2u6PWNKMNgW/qUIq13W9PQxzIiQxrT7ZqPFJu75C1KdXXUG5lghU7EBAGehHC/5BqFjs9SuYJkV1RrchMEzytrJIQ7Zp4CnOU6Q1rEhFTaMk/s=";
                string encodedKey = "2zpVbIxqvjSfJo7zkXzl2A==";
                string encodedIV = "5WOQPdmB/BkECmuPdNTaLw==";
                Aes128Decrypt(encodedKey, encodedIV, encodedPayload);

JAVA应用程序加密后的数据如下所示

<rson>
    <firstName>Rennish</firstName>
    <lastName>Joseph</lastName>
    <accountNumber>12345678910</accountNumber>
    <ssn>123456</ssn>
</person>

1 个答案:

答案 0 :(得分:1)

有趣的问题。

我认为加密和解密双方都可以正常工作。

如果加密消息的一部分在传输中丢失,则由于雪崩效应而无法对其进行解密。所以在纯文本中似乎缺少字符。

这可能是纯文本邮件中的编码问题。您编码的字节数和它们解码的字节数可能相同。解释它们的方式可能不是。

现在有两种选择:

<person>变为<rson>或变为rson>并且存在复制粘贴错误。

如果后一种情况属实,那么我们将缺少3个字节。这让我觉得协议可能会假定存在一个字节顺序标记,并且只删除前3个字节来摆脱它。

如果是前一种情况,您会遇到一些非常奇怪的编码问题。因为所有缺失的字符似乎都在ascii范围内,所以他们不应该有这些问题。

虽然容易测试:
 1.尝试使用字节顺序标记发送  2.尝试使用<XXperson>发送  3.尝试发送一些带重音符号的字符。