Console.WriteLine在大量二进制零后不显示行

时间:2011-01-30 14:26:19

标签: c# debugging

程序永远不会打印出“测试”,除非我在它上面设置一个断点并跨过我自己。我不明白发生了什么。感谢任何帮助。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        string testKey = "lkirwf897+22#bbtrm8814z5qq=498j5";
        string testIv = "741952hheeyy66#cs!9hjv887mxx7@8y";
        string testValue = "random";

        string encryptedText = EncryptRJ256(testKey, testIv, testValue);
        string decryptedText = DecryptRJ256(testKey, testIv, encryptedText);

        Console.WriteLine("encrypted: " + encryptedText);
        Console.WriteLine("decrypted: " + decryptedText);
        Console.WriteLine("test");
    }

    public static string DecryptRJ256(string key, string iv, string text)
    {

        string sEncryptedString = text;

        RijndaelManaged myRijndael = new RijndaelManaged();
        myRijndael.Padding = PaddingMode.Zeros;
        myRijndael.Mode = CipherMode.CBC;
        myRijndael.KeySize = 256;
        myRijndael.BlockSize = 256;

        byte[] keyByte = System.Text.Encoding.ASCII.GetBytes(key);
        byte[] IVByte = System.Text.Encoding.ASCII.GetBytes(iv);

        ICryptoTransform decryptor = myRijndael.CreateDecryptor(keyByte, IVByte);

        byte[] sEncrypted = Convert.FromBase64String(sEncryptedString);

        byte[] fromEncrypt = new byte[sEncrypted.Length + 1];

        MemoryStream msDecrypt = new MemoryStream(sEncrypted);
        CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);

        csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

        return Encoding.ASCII.GetString(fromEncrypt);

    }


    public static string EncryptRJ256(string key, string iv, string text)
    {

        string sToEncrypt = text;

        RijndaelManaged myRijndael = new RijndaelManaged();
        myRijndael.Padding = PaddingMode.Zeros;
        myRijndael.Mode = CipherMode.CBC;
        myRijndael.KeySize = 256;
        myRijndael.BlockSize = 256;


        byte[] keyByte = Encoding.ASCII.GetBytes(key);
        byte[] IVByte = Encoding.ASCII.GetBytes(iv);

        ICryptoTransform encryptor = myRijndael.CreateEncryptor(keyByte, IVByte);

        MemoryStream msEncrypt = new MemoryStream();
        CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);

        byte[] toEncrypt = System.Text.Encoding.ASCII.GetBytes(sToEncrypt);

        csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
        csEncrypt.FlushFinalBlock();

        byte[] encrypted = msEncrypt.ToArray();

        return Convert.ToBase64String(encrypted);

    }
}

编辑:

尝试Debug.WriteLine

        Debug.WriteLine("encrypted: " + encryptedText);
        Debug.WriteLine("decrypted: " + decryptedText);
        Debug.WriteLine("test");

输出:

已加密:T4hdAcpP5MROmKLeziLvl7couD0o + 6EuB / Kx29RPm9w =
解密:randomtest

不确定为什么它不打印行终止符。

3 个答案:

答案 0 :(得分:5)

        myRijndael.Padding = PaddingMode.Zeros;
        myRijndael.BlockSize = 256;

这是问题的根源,您加密的数据用零填充以获得32字节(32 x 8 = 256)的倍数的块大小。您将这些二进制零返回到解密值中。关于它们的棘手问题是调试器无法显示它们。哪个好,你希望通过ASCII往返的值,你可以在解密后再次删除零。解密代码也需要一些工作,你对解密数据的大小有太多考虑。修正:

        MemoryStream fromEncrypt = new MemoryStream();
        MemoryStream msDecrypt = new MemoryStream(sEncrypted);
        CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);

        byte[] buffer = new byte[4096];
        for (; ; ) {
            int len = csDecrypt.Read(buffer, 0, buffer.Length);
            if (len == 0) break;
            fromEncrypt.Write(buffer, 0, len);
        }

        var result = Encoding.ASCII.GetString(fromEncrypt.GetBuffer(), 0, (int)fromEncrypt.Length);
        return result.Trim('\0');

你应该顺便处理流,使用使用语句。

答案 1 :(得分:0)

虽然这适用于我在Linux上使用Mono,但我确实看到decryptedText长度为33个字符 - 它由字符'r','a','n','d','o','m组成'跟随了27个NUL角色。 (我以前推测填充字节可能是未初始化的,但是查看它看起来很明确的代码。)我推测Visual Studio中的控制台输出窗口将NUL字符解释为输出结束,因此停止之后打印其他任何东西 - 包括WriteLine的行终止符和“test”字符串。我这里没有Visual Studio来测试它,但我认为你应该能够轻松地验证或反驳它。

答案 2 :(得分:0)

您的加密/解密代码中存在一个问题:由于您使用PaddingMode.Zeros,因此在解密后,您无法说出原始数据的结束位置,并且您收到了“随机”后跟零字节。如果你想切换到例如PaddingMode.PKCS7,并且正确使用CryptoStream.Read调用的返回值,您只会收到原始文本,即“随机”:

var decryptedSize = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt, 0, decryptedSize);

即使我认为不应该将NUL字节写入控制台是一个问题,我肯定会先尝试删除它们,特别是在看到这种奇怪的行为时。