简体   繁体   English

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

[英]C# encrypted data getting truncated using Java decryption code

All,I am posting some encrypted xml data(Using AES-128 ) to another application that uses Java to decrypt.When the Java code decrypts the xml,the start tag of the xml is getting truncated and fails validation.I don't have access to their code base .I can decrypt the same data using C# without any data loss.Please see the code I use to encrypt and Decrypt the data .所有,我将一些加密的 xml 数据(使用 AES-128 )发布到另一个使用 Java 解密的应用程序。当 Java 代码解密 xml 时,xml 的开始标记被截断并且验证失败。我没有访问他们的代码库。我可以使用 C# 解密相同的数据而不会丢失任何数据。请参阅我用来加密和解密数据的代码。 I have researched this and based on the research ,I added the FlushFinalBlocks() and Close() to the CryptoStream in the encryption logic ,but this doesnt seem to fix the issue.我对此进行了研究,并根据研究结果,在加密逻辑中将 FlushFinalBlocks() 和 Close() 添加到 CryptoStream 中,但这似乎并没有解决问题。

Encryption Code:加密代码:

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  ;
        }

Decryption Code:解密代码:

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;


        }

Testing Code:测试代码:

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);

Data after encryption at the JAVA application looks like this JAVA 应用程序加密后的数据如下所示

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

Interesting problem.有趣的问题。

I think the encryption and decryption works fine on both sides.我认为加密和解密在双方都很好。

If part of the encrypted message was lost in transmission you would not be able to decrypt it due to the avalanche effect.如果部分加密消息在传输过程中丢失,由于雪崩效应,您将无法解密它。 So it appears that characters go missing in the plain text.因此,纯文本中似乎缺少字符。

This might be an encoding issue in the plain text message.这可能是纯文本消息中的编码问题。 The bytes you have encoded and the bytes they decoded are probably the same.您编码的字节和它们解码的字节可能相同。 The way they are interpreted might not be.它们的解释方式可能不是。

Now there are two options here:现在这里有两个选择:

Either <person> becomes <rson> or it becomes rson> and there was a copy-paste mistake. <person>变为<rson>或变为rson>并且存在复制粘贴错误。

If the latter case is true then we're missing 3 bytes.如果后一种情况为真,那么我们将丢失 3 个字节。 This makes me think that the protocol might presume the presence of a byte order marker andsimply removes the first 3 bytes to get rid of it.这让我认为该协议可能会假定存在字节顺序标记并简单地删除前 3 个字节以摆脱它。

If the former case you'd have some very weird encoding issues.如果是前一种情况,您会遇到一些非常奇怪的编码问题。 As all missing characters appear to be in the ascii range so they shouldn't have these issues.由于所有丢失的字符似乎都在 ascii 范围内,因此它们不应该有这些问题。

Easy to test though:易于测试:
1. Try sending with a byte order marker. 1. 尝试使用字节顺序标记发送。
2. Try sending with <XXperson> 2. 尝试用<XXperson>发送
3. Try sending some characters with accents and the like. 3. 尝试发送一些带有重音等的字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM