使用 S/MIME (PHP) 发送带有附件的电子邮件

Posted

技术标签:

【中文标题】使用 S/MIME (PHP) 发送带有附件的电子邮件【英文标题】:Sending an e-mail with an attachment using S/MIME (PHP) 【发布时间】:2012-02-18 17:01:16 【问题描述】:

我正在尝试从 php 发送带有附件的加密电子邮件,但是,我的电子邮件只是在电子邮件客户端(在本例中为 MS Outlook)中显示为纯文本。 这是我用来发送电子邮件的代码:

$semi_rand = md5(time());   
$mime_boundary = "==Multipart_Boundary_x$semi_randx";   
$fileatt = "\path\to\attachment";
$headers = array();
$headers['From'] = $email_from;
$headers['Subject'] = $email_subject; 
$headers['MIME-Version'] = "1.0";
$headers['Content-Type'] = "multipart/mixed; boundary=\"$mime_boundary\"";    

$file = fopen($fileatt,'rb');   
$data = fread($file,filesize($fileatt));
$data = chunk_split(base64_encode($data));     
fclose($file);   

//message part
$email_message = "This is a multi-part message in MIME format.\n\n" .   
                "--$mime_boundary\n" .   
                "Content-Type:text/html; charset=\"UTF-8\"\n" .   
                "Content-Transfer-Encoding: 7bit\n\n
                                     Please find the file attached\n\n";   


//file part
$email_message .= "--$mime_boundary\n" .   
                  "Content-Type: $fileatt_type;\n" .   
                  " name=\"$fileatt_name\"\n" .   
                  "Content-Transfer-Encoding: base64\n\n" .   
                 $data . "\n\n" .   
                  "--$mime_boundary--\n";   

$mfile = fopen("msg.txt", "w");
fwrite($mfile, $email_message);
fclose($mfile);


$key = file_get_contents("mailcert.cer");

$encrypt = openssl_pkcs7_encrypt("msg.txt", "enc.txt", $key, $headers);
if($encrypt)
    $data = file_get_contents("enc.txt");
    $parts = explode("\n\n", $data, 2);

    // Send mail
    $ok = mail($email_to, $email_subject, $parts[1], $parts[0]);
  

脚本有效,电子邮件已发送,并且可以在 Outlook 中对其进行解密,但是,结果如下所示:

--==Multipart_Boundary_x6434b5a09f1f49c571a633802cd36772x

Content-Type:text/html; charset="UTF-8"
Content-Transfer-Encoding: 7bit

Please find the file attached

--==Multipart_Boundary_x6434b5a09f1f49c571a633802cd36772x
Content-Type: application/octet-stream;
 name="1327490599scrippie.txt"
Content-Transfer-Encoding: base64

JG9sZElwID0gIjE5NS40Ni4zOS43MyINCiRuZXdJcCA9ICIqIg0KDQojIEdldCBhbGwgb2JqZWN0
cyBhdCBJSVM6Ly9Mb2NhbGhvc3QvVzNTVkMNCiRpaXNPYmplY3RzID0gbmV3LW9iamVjdCBgDQog
ICAgU3lzdGVtLkRpcmVjdG9yeVNlcnZpY2VzLkRpcmVjdG9yeUVudHJ5KCJJSVM6Ly9Mb2NhbGhv
[etc....]

--==Multipart_Boundary_x6434b5a09f1f49c571a633802cd36772x--

还有其他发送带有附件的加密电子邮件的方法吗?或者有解决这个问题的办法吗?

【问题讨论】:

Should I use php mail function or phpmailer?的可能重复 谢谢马里奥,但不,这个问题与我的问题几乎没有任何关系,只是它是关于从 PHP 发送邮件的...... 缺少分号不会发生在 phpmailer 或 switftmailer 中。不要费心修补你的代码。扔掉它。 没错,如果您使用 swiftmailer,从 PHP 发送电子邮件可能不太容易出错,但是,我的问题特别是关于发送带有附件的 加密 电子邮件,这在另一个问题。如果使用 swiftmailer 可以解决我的问题,那很好,但这并不能使问题相同。 不,它被取消资格为 exact 重复。您可以保留两行加密代码,但要避开冗长的手动 MIME 正文连接所带来的实际错误。 【参考方案1】:

解决此问题的方法是在包含该消息的文件中包含原始消息的标头。

我在将文件写入磁盘之前添加了类似的内容:

foreach($headers as $headerkey => $headerval)
    $email_message = $headerkey . ": " . $headerval . "\r\n" . $email_message;

然后,从数组中删除 MIME-version 和 Content-Type 标头,然后再将其传递给 openssl_pkcs7_encrypt() 函数。

【讨论】:

以上是关于使用 S/MIME (PHP) 发送带有附件的电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有附件的 PEAR Mail 包使用 PHP 发送电子邮件

php发送带有PDF附件的电子邮件

在php中发送带有多个附件的电子邮件

PHP不发送带有附件的邮件

PHP 发送带有 PDF 附件的电子邮件

在 PHP 中,如何发送带有附件的 HTML 电子邮件?