我设法使用 PHPMailer 找到了解决方案,它也适用于常规 PHP。它将对电子邮件进行签名和加密,我找不到使用 PHPMailer(签名和加密)仅签名的方法,所以我在 class.phpmailer.php 中添加了一些代码。它仍然需要在加密错误的情况下添加一些错误处理,但到目前为止效果很好。
对于 CakePHP 2.x:
下载 PHPMailer 并将其添加到您的 Vendors 文件夹 (project_name/app/vendor)
在函数的开头添加这一行:
App::import('Vendor','PHPMailer/PHPMailerAutoload');
从这里它对于 PHP 或 CakePHP 是一样的:
$mail = new PHPMailer();
$mail->setFrom('from_who@email', 'Intranet');
//Set who the message is to be sent to
$mail->addAddress('to_who@email', 'Ricardo V');
//Set the subject line
$mail->Subject = 'PHPMailer signing test';
//Replace the plain text body with one created manually
$mail->Body = "some encrypted text...";
//Attach an image file
$mail->addAttachment('D:/path_to_file/test.pdf');
$mail->sign(
'app/webroot/cert/cert.crt', //The location of your certificate file
'app/webroot/cert/private.key', //The location of your private key
file
'password', //The password you protected your private key with (not
//the Import Password! may be empty but parameter must not be omitted!)
'app/webroot/cert/certchain.pem', //the certificate chain.
'1', //Encrypt the email as well, (1 = encrypt, 0 = dont encrypt)
'app/webroot/cert/rvarilias.crt'//The location of public certificate
//to encrypt the email with.
);
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
然后我们需要对class.phpmailer.php进行一些修改
将 2368 到 2390 的行替换为:
$sign = @openssl_pkcs7_sign(
$file,
$signed,
'file://' . realpath($this->sign_cert_file),
array('file://' . realpath($this->sign_key_file),
$this->sign_key_pass),
null,
PKCS7_DETACHED,
$this->sign_extracerts_file
);
if ($this->encrypt_file == 1) {
$encrypted = tempnam(sys_get_temp_dir(), 'encrypted');
$encrypt = @openssl_pkcs7_encrypt(
$signed,
$encrypted,
file_get_contents($this->encrypt_cert_file),
null,
0,
1
);
if ($encrypted) {
@unlink($file);
$body = file_get_contents($encrypted);
@unlink($signed);
@unlink($encrypted);
//The message returned by openssl contains both headers
and body, so need to split them up
$parts = explode("\n\n", $body, 2);
$this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
$body = $parts[1];
} else {
@unlink($file);
@unlink($signed);
@unlink($encrypted);
throw new phpmailerException($this->lang('signing') .
openssl_error_string());
}
} else {
if ($signed) {
@unlink($file);
$body = file_get_contents($signed);
@unlink($signed);
//The message returned by openssl contains both headers
and body, so need to split them up
$parts = explode("\n\n", $body, 2);
$this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
$body = $parts[1];
} else {
@unlink($file);
@unlink($signed);
throw new phpmailerException($this->lang('signing') .
openssl_error_string());
}
}
}
然后寻找:
public function sign($cert_filename, $key_filename, $key_pass,
$extracerts_filename = '')
{
$this->sign_cert_file = $cert_filename;
$this->sign_key_file = $key_filename;
$this->sign_key_pass = $key_pass;
$this->sign_extracerts_file = $extracerts_filename;
}
并将其更改为:
public function sign($cert_filename, $key_filename, $key_pass,
$extracerts_filename = '', $and_encrypt ='0', $encrypt_cert = '')
{
$this->sign_cert_file = $cert_filename;
$this->sign_key_file = $key_filename;
$this->sign_key_pass = $key_pass;
$this->sign_extracerts_file = $extracerts_filename;
$this->encrypt_file = $and_encrypt;
$this->encrypt_cert_file = $encrypt_cert;
}
寻找:
protected $sign_extracerts_file = '';
并在其后添加以下行:
protected $encrypt_cert = '';
protected $and_encrypt = '';
通过对 phpmailer 的这些更改,您可以发送签名的电子邮件或签名和加密的电子邮件。它也适用于附件。
我希望它对某人有所帮助。
*对于普通的 php,只是不要添加该行:
App::import('Vendor','PHPMailer/PHPMailerAutoload');