Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用非ASCII内容类型从php发送加密邮件_Php_Email_Encryption - Fatal编程技术网

使用非ASCII内容类型从php发送加密邮件

使用非ASCII内容类型从php发送加密邮件,php,email,encryption,Php,Email,Encryption,我正在尝试使用下面的代码发送加密邮件,其中明文为text/html,字符集为utf-8。 无论如何,我无法正确显示邮件(在MS Outlook中)。 您可能会注意到,我(同时)尝试将相关的内容类型:头添加到要加密的数据文件中,并显示在调用openssl\u pkcs7\u encrypt的头中(并尝试了各种其他组合) 当消息未加密发送时,所需的内容类型适用于该消息,但它不能处理加密消息。结果总是好像“内部”内容类型是text/plain;字符集=ascii 我尝试在加密之前为数据文件预加头,只是

我正在尝试使用下面的代码发送加密邮件,其中明文为text/html,字符集为utf-8。 无论如何,我无法正确显示邮件(在MS Outlook中)。 您可能会注意到,我(同时)尝试将相关的
内容类型:
头添加到要加密的数据文件中,并显示在调用
openssl\u pkcs7\u encrypt
头中(并尝试了各种其他组合)

当消息未加密发送时,所需的内容类型适用于该消息,但它不能处理加密消息。结果总是好像“内部”内容类型是
text/plain;字符集=ascii

我尝试在加密之前为数据文件预加头,只是因为我想我在SE上找到了一些类似的建议,用于类似的情况。但显然,这只会使标题行作为解密消息的一部分出现(换句话说,提交给
openssl\u pkcs7\u encrypt
的文件实际上应该只是“纯”内容(正如我最初怀疑的那样)

但是,在headers参数中包含它也没有帮助:在enncryped文件中存在的头中,添加了一个带有正确的“外部”S/MIME内容类型的头,它覆盖了给定的“内部”内容类型

问题:我应该在哪里以及如何结合使用
openssl\u pkcs7\u encrypt()
mail()
指定加密邮件的“内部”内容类型

$hdr_to = implode(',',$empfaenger);
$hdr_subject = '=?UTF-8?q?' . quoted_printable_encode($subject) . '?=';
$other_headers = array(
    "From" => $hdr_from,
    "Content-Type" =>  "text/html; charset=utf-8",
    "X-Mailer" => "PHP/".phpversion()
);
$mailbody = wordwrap($_REQUEST['message']);

//write msg to disk
$msg_fn = tempnam("/tmp","MSG");
$enc_fn = tempnam("/tmp","ENC");
$fp = fopen($msg_fn, "w");
fwrite($fp, 'Content-Type: ' . $other_headers['Content-Type'] . CRLF . CRLF);
fwrite($fp, $mailbody);
fclose($fp);

// Encrypt message
$enc_ok = openssl_pkcs7_encrypt($msg_fn,$enc_fn,$pubkeys,$other_headers,PKCS7_TEXT,1);
//$enc_ok = false; // for debugging: simulate encryption failure 
if (!$enc_ok) {
    // Will try to send unencrypted instead
} else {
    // Seperate headers and body for mail()
    $data = str_replace("\n",CRLF,file_get_contents($enc_fn));
    $parts = explode(CRLF.CRLF, $data, 2);
    $mailbody = $parts[1];
    $other_headers = $parts[0];
}

// Send mail
$mail_ok = mail($hdr_to, $hdr_subject, $mailbody, $other_headers);

问题在于
PKCS7_TEXT
标志作为加密函数的参数


我的预期媒体类型是
text/html;charset=utf-8
,即

  • 属于类型
    文本
  • 属于子类型
    html
  • 参数的
    charset=utf-8
从表面上看,类型与名称
PKCS7_TEXT的含义相匹配

将文本/普通内容类型头添加到加密/签名的邮件中。如果解密或验证,则会从输出中删除这些头-如果解密或验证的邮件不是MIME类型的文本/普通,则会发生错误

准确地说,所述标题和一个空行(将其与消息正文分开)似乎是预先加好的,这会将以前存在的任何标题行(
内容类型:
或其他)变成正文的一部分

因此,简单的解决方案是不使用
PKCS7_TEXT
标志(除非您的消息是纯ASCII²文本)



²对于拉丁语-1文本也可以,但我不会指望它。在上面引用的所有描述表明会发生错误之后,UTF-8文本再次成功解密(即,没有显式错误),但显示通常与代码页相关的显示人工制品。

内容类型标头必须在邮件正文前加上前缀(用空行分隔),因此它位于加密部分内。@not2savvy您的意思是,就像我按照
fwrite($fp,'Content-type:'。$other_标头['Content-type'].CRLF所做的那样。$other_标头['Content-type'].CRLF)
?抱歉,我忽略了这一部分。我认为这是正确的。您的外部内容类型可以被覆盖。您可以将$enc_ok中的结果添加到您的问题中吗?另外,您是否确保
爆炸(CRLF.CRLF,…
按预期工作,因为我不确定它是否只是LF本身。@not2savvy无需担心。
$enc_ok
只是
true
因为加密确实有效(即,证书没有问题);举个简单的例子,我可能已经排除了测试和明文回退分支。--是的,我注意到
$enc_fn
的内容只有LF换行符,when(IIRC)CRLF是必需的。由于前面一行的
str\u replace
,explode工作正常。我分心了。我的意思是询问
$enc\u fn
的内容。注意:虽然非ascii文本可以很好地加密和解密,但邮件客户端在处理非ascii文本时如何处理还没有定义,因此除非encod正确打印(base-64或引用可打印)。