输出无效
我有一个 PHP 程序,它将 PDF 文件加密为 .xxx 文件,该输出由 C# 程序读取,该程序将该 .xxx 文件解密回 PDF 文件。
我的问题是,当我打开由 C# 解密的文件时,PDF 阅读器告诉我该文件已损坏..当我在 PHP 中加密纯文本并在 C# 上解密时,我得到了我加密的文件..所以问题只出现在 PDF 文件中,或者换句话说,它出现在 BINARY 文件中,
有什么建议吗?!
注意:
- 在 PHP 中,我使用 mcrypt 扩展 Rijndael 算法 CBC PKCS7 填充(填充是手动完成的)
- 在 C# 中,我使用 RijndaelManaged 类来加密和解密数据
编辑:
这是我在 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;
}
:这是 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;
}
以下是我在 C# 中调用解密的方式以及如何编写输出:
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();
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:
- In PHP I use mcrypt extension Rijndael algorithm CBC PKCS7 padding (padding is done manually)
- 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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为问题在于您在 PHP 和 C# 端都将二进制 PDF 数据视为文本。
如果
encoded
表示二进制数据,则没有任何意义。您可能应该跳过此步骤并将DecryptString()
定义为返回byte[]
。然后也重命名它。如果你确实想要它作为一个字符串,你可能会更好地使用 ASCII 或 ANSI 编码:
但错误可能已经发生在 PHP 端,我不知道。
另外,我刚刚指出:
这是创建 BinaryWriter 的一种非常复杂的方法。将不会使用编码。这
将写入带有长度前缀的字符串,这肯定会使您的 PDF 无效。
当您将 Decrypt 的返回值保留为
string
时,请使用当您将其返回为
byte[]
时(推荐),请使用I think the problem is that you treat the binary PDF data as text on both the PHP and the C# side.
makes no sense if
encoded
represents binary data. You should probably skip this step and define yourDecryptString()
as returningbyte[]
. And then rename it too.If you do want it as a string you might have better luck with ASCII or ANSI encoding:
but the error may already be happening on the PHP side, I can't tell.
Additional, I just noted:
This is a very over-complicated way to create a BinaryWriter. The Encoding will not be used. And
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
, useAnd when you return it as
byte[]
(recommended), use