Я много искал в Интернете, но я не нашел ответа, возможно ли отправлять зашифрованные письма S / MIME с использованием PHP? если да, то как? (Я использую CakePHP 2.x)
заранее большое спасибо
Мне удалось найти решение этой проблемы с помощью PHPMailer, это относится и к обычному PHP. Он будет подписывать и шифровать электронную почту, я не смог найти способ сделать как с PHPMailer (подписать и зашифровать) только подписать, поэтому я добавил некоторый код в class.phpmailer.php. Все еще нужно добавить некоторую обработку ошибок в случае ошибки шифрования, но пока работает хорошо.
для CakePHP 2.x:
Загрузите PHPMailer и добавьте его в папку Vendors (имя_проекта / 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');
Других решений пока нет …