【问题标题】:PHPMailer and S/MIMEPHPMailer 和 S/MIME
【发布时间】:2012-10-04 21:25:05
【问题描述】:

对于学校作业,我们必须发送来自银行的安全电子邮件(我们就是银行)。为了保护这些电子邮件,我使用 PHPMailer。 PHPMailer 包含一个 Sign($cert_filename, $key_filename, $key_pass) 方法,该方法使用证书对电子邮件进行签名。我猜这会使电子邮件“安全”,并且客户可以真正知道是银行发送电子邮件。我正在使用 SMTP 通过我自己的域发送电子邮件。

为了获得证书,我在this website 创建了一个证书,该证书已安装在我的浏览器中。

现在的问题是:如何使用该证书来签署我使用 PHP 脚本和 PHPMailer 发送的电子邮件?我已经从我的浏览器 (FF) 中导出了证书,这会生成一个 .p12 文件,但我认为 .p12 文件不是我想要的。

任何帮助将不胜感激。

【问题讨论】:

  • 您可以使用openssl 将 pkcs12 文件(您可能拥有)转换为 PHPMailer 的 .pem 证书。见这篇文章:adam-makes-websites.com/discoveries/…
  • 感谢您的帮助,我如何检查电子邮件是否已签名?我正在使用 gmail 来查看邮件。
  • 如果您在 Gmail 中查看邮件源(“显示原件”),您应该会看到一个 base64 块,前面有一个带有 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; 的标头
  • 再次感谢,我已完成所有更改,但电子邮件尚未标记为已签名。正文也是空的(白色电子邮件,但主题有效)。如果我删除符号变量,则电子邮件显示正常。我正在使用 SMTP。有什么想法吗?
  • 启用error_reporting,在openssl_*函数调用Marin told you to edit之前删除@,或者使用set_error_handler("var_dump");来显示任何错误。

标签: php security phpmailer digital-certificate smime


【解决方案1】:

在您的 class.phpmailer.php 文件中更改数据:

public   $sign_cert_file = ’’; 
public   $sign_key_file  = ’’; 
public   $sign_key_pass  = ’’; 

比出现的定位:

if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {

并更改为:

if (@openssl_pkcs7_sign($file, $signed, file_get_contents($this->sign_cert_file), array(file_get_contents($this->sign_key_file), $this->sign_key_pass), null)){

这意味着你是通过对象 $this->sign_key_file 而不是文件包含 file://

比更改您的临时名称:

$file = tempnam(’’, ’mail’);
...
$signed = tempnam("", "signed");

到:

$file = tempnam(’./tmp/’, ’mail’);
...
$signed = tempnam("./tmp/", "signed");

这意味着您正在使用 tmp 目录服务器。

现在如何展示发送和放置数据证书文件的示例:

require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsMail();

$mail->AddAddress("email@example.com");
$mail->Subject = "Test 1";
$mail->Body = "Test 1 of PHPMailer.";

// CUSTOMISED SIGN EMAIL : START
$mail->sign_cert_file="/xxx/key.pem";
$mail->sign_key_file="/xxx/key.pem";
$mail->sign_key_pass="yyy";
// CUSTOMISED SIGN EMAIL : END

$mail->Send(); // Send encrypted email!

【讨论】:

  • 我已完成所有更改,但电子邮件尚未标记为已签名。正文也是空的(白色电子邮件,但主题有效)。如果我删除符号变量,则电子邮件显示正常。我正在使用 SMTP。有什么想法吗?
  • 或者是由于操作无法处理或SSL签名配置中的编码问题。
【解决方案2】:

您现在可以使用sign() 函数添加签名证书:

require_once 'PHPMailerAutoload.php';
$mail = new PHPMailer();
$mail->AddAddress("email@example.com");
$mail->Subject = "Test";
$mail->Body = "Test";

$mail->sign(
    'cert.crt',
    'cert.key',
    'password',//required even if empty
    'certchain.pem'
);

if( !$mail->Send() ){
    echo $mail->ErrorInfo;
}

https://github.com/PHPMailer/PHPMailer/blob/master/examples/smime_signed_mail.phps#L77

【讨论】:

    猜你喜欢
    • 2011-09-07
    • 2016-11-20
    • 2010-09-12
    • 2019-03-04
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多