dongmi5015 2012-01-14 13:19
浏览 25
已采纳

输出无效

I have a PHP program that encrypts a PDF file into .xxx file this output is being read by a C# program that decrypts this .xxx file back into PDF file.

My problem is that when I open the file decrypted by C# , the PDF reader tells me that the file is corrupted .. when I encrypt plain text in PHP and decrypt on C# I got the file I encrypted .. so the problem is appearing only in PDF files or in other words it appears in BINARY files

any suggestions ?!

Notes:

  1. In PHP I use mcrypt extension Rijndael algorithm CBC PKCS7 padding (padding is done manually)
  2. In C# I use RijndaelManaged class to encrypt and decrypt data

Edit:

Here is encryption method that I use in PHP:

    function encrypt($key, $iv, $text) {
        ini_set ( 'memory_limit', '-1' );
        $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
        $mcrypt_mode = MCRYPT_MODE_CBC;
        $text=addpadding($text,mcrypt_get_block_size($mcrypt_cipher,'cbc'));
        $encrypted = rtrim ( mcrypt_encrypt ( $mcrypt_cipher, $key, $text, $mcrypt_mode, $iv ), "\0" );
        $encrypted = base64_encode ( $encrypted );
        return $encrypted;
    }

And here is the decryption method in C#:

    public static string DecryptString(string message, string KeyString, string IVString)
    {
        byte[] Key = Encoding.UTF8.GetBytes(KeyString);
        byte[] IV = Encoding.UTF8.GetBytes(IVString);

        string decrypted = null;
        RijndaelManaged rj = new RijndaelManaged();
        rj.BlockSize = 256;
        rj.Key = Key;
        rj.IV = IV;
        rj.Mode = CipherMode.CBC;
        rj.Padding = PaddingMode.PKCS7;
        try
        {
            MemoryStream ms = new MemoryStream();
            //Encoding enc = new UTF8Encoding();
            byte[] messageBytes = Convert.FromBase64String(message);
            using (CryptoStream cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Write))
            {
                //byte[] messageBytes = enc.GetBytes(message);

                cs.Write(messageBytes, 0, messageBytes.Length);
                cs.Close();
            }
            byte[] encoded = ms.ToArray();
            decrypted = Encoding.UTF8.GetString(encoded);

            ms.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("An error occurred:"+ e.Message);
        }
        finally
        {
            rj.Clear();
        }

        return decrypted;
    }

and here is how I call the decrypt in C# and how I write output:

                string Key = cryptography.MD5("X-Ware" + cryptography.MD5("123"));
                string IV = cryptography.MD5("XWare");
                string decrypted = cryptography.DecryptString(contents, Key, IV);
                string outputFilename = cryptography.MD5(OFD.FileName) + ".tmp";

                StreamWriter sw = new StreamWriter("C:\\Windows\\Temp\\" + outputFilename, false, Encoding.UTF8);
                BinaryWriter bw = new BinaryWriter(sw.BaseStream, Encoding.UTF8);
                //sw.Write(decrypted);
                bw.Write(decrypted);
                sw.Close();
                bw.Close();
  • 写回答

1条回答 默认 最新

  • dongshilve4392 2012-01-14 13:59
    关注

    I think the problem is that you treat the binary PDF data as text on both the PHP and the C# side.

     decrypted = Encoding.UTF8.GetString(encoded);
    

    makes no sense if encoded represents binary data. You should probably skip this step and define your DecryptString() as returning byte[]. And then rename it too.

    If you do want it as a string you might have better luck with ASCII or ANSI encoding:

     decrypted = Encoding.ASCII.GetString(encoded);
    

    but the error may already be happening on the PHP side, I can't tell.

    Additional, I just noted:

        StreamWriter sw = new StreamWriter("C:\\Windows\\Temp\\" + outputFilename,  
               false, Encoding.UTF8);
        BinaryWriter bw = new BinaryWriter(sw.BaseStream, Encoding.UTF8);
    

    This is a very over-complicated way to create a BinaryWriter. The Encoding will not be used. And

     bw.Write(decrypted);
    

    This will write the string with a length-prefix, that certainly will make your PDF invalid.

    When you keep the return of Decrypt as string, use

      File.WriteAllText("C:\\Windows\\Temp\\" + outputFilename, decrypted);
    

    And when you return it as byte[] (recommended), use

     File.WriteAllBytes("C:\\Windows\\Temp\\" + outputFilename, decrypted);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办