My example of working code to sign the letter to get the balance of the cashier with Yandex Money.
Snippet pulled from the code, because please do not criticize severely
(OpenSSL подпись письма на получения баланса по кассе Яндекс Деньги)
private function _make_message($data)
{
$tmp_file_msg_raw = realpath(tempnam('C:\Temp', 'ymr_'));
$tmp_file_msg_sign = realpath(tempnam('C:\Temp', 'yms_'));
$EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
$EOL2 = "\n\n";
$boundary = md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
$fd = fopen($tmp_file_msg_raw, 'w');
if(!$fd) {
$error = "Could not open temporary file $tmp_file_msg_raw.";
return array("status" => false, "error_msg" => $error, "error_no" => 0);
}
fwrite($fd, $data);
fclose($fd);
if(!@openssl_pkcs7_sign(
$tmp_file_msg_raw,
$tmp_file_msg_sign,
'file://' . $this->_deposit_crt_sign,
['file://' . $this->_deposit_key, $this->_config['secret_keyword']],
[],
PKCS7_BINARY))
{
unlink($tmp_file_msg_raw);
unlink($tmp_file_msg_sign);
$error = "Could not sign data: ".openssl_error_string();
return FALSE;
}
$signed_data = file_get_contents($tmp_file_msg_sign);
$signed_data_array = explode($EOL2, $signed_data);
$signed_data = $signed_data_array[1];
$signed_data = "-----BEGIN PKCS7-----\n" . $signed_data . "\n-----END PKCS7-----";
$multipart = '--' . $boundary . $EOL;
$multipart .= 'Content-Disposition: form-data; name=smime; filename=smime.p7m' . $EOL;
$multipart .= 'Content-Type: application/pkcs7-mime' . $EOL;
$multipart .= $EOL; // раздел между заголовками и телом html-части
$multipart .= $signed_data;
$multipart .= $EOL . '--' . $boundary . '--' . $EOL;
unlink($tmp_file_msg_raw);
unlink($tmp_file_msg_sign);
return [
'headers' => [
'MIME-Version: 1.0',
"Content-Type: multipart/form-data; boundary=\"$boundary\"",
],
'body' => $multipart
];
}
private function _read_message($data)
{
$EOL = "\r\n";
$pkcs7_headers = 'MIME-Version: 1.0' . $EOL;
$pkcs7_headers .= 'Content-Disposition: attachment' . $EOL;
$pkcs7_headers .= 'Content-Type: application/x-pkcs7-mime' . $EOL;
$pkcs7_headers .= 'Content-Transfer-Encoding: base64' . $EOL;
$pkcs7_headers .= $EOL;
$pkcs7_message = $pkcs7_headers . $data;
$file_pkcs7_msg = realpath(tempnam('C:\Temp', 'ymm'));
$file_pkcs7_outfilename = realpath(tempnam('C:\Temp', 'ymo_'));
$file_pkcs7_content = realpath(tempnam('C:\Temp', 'ymc_'));
$fd_message_response = fopen($file_pkcs7_msg, 'a');
if(!$fd_message_response) {
$error = "Could not open temporary file $file_pkcs7_msg.";
return array("status" => false, "error_msg" => $error, "error_no" => 0);
}
fwrite($fd_message_response, $pkcs7_message);
fclose($fd_message_response);
if (!@openssl_pkcs7_verify(
$file_pkcs7_msg,
PKCS7_BINARY,
$file_pkcs7_outfilename,
[$this->_deposit_crt_verify],
$this->_deposit_crt_verify,
$file_pkcs7_content))
{
// TODO
};
$data = file_get_contents($file_pkcs7_content);
unlink($file_pkcs7_msg);
unlink($file_pkcs7_outfilename);
unlink($file_pkcs7_content);
//while ($msg = openssl_error_string()) echo $msg . "<br />\n";
return $data;
}
$data = '<?xml version="1.0" encoding="UTF-8"?><balanceRequest agentId="123456" clientOrderId="1" requestDT="2015-02-17T16:21:22+04:00"/>';
$data = $this->_make_message($data);
$url = $this->_config['uri_api_deposition'].'webservice/deposition/api/balance';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $data['headers']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data['body']);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, 'Ymoney CollectMoney');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLCERT, $this->_ssl_crt);
curl_setopt($ch, CURLOPT_SSLKEY, $this->_ssl_key);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->_config['secret_keyword']);
curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
$response = curl_exec($ch);
//var_dump($response);
curl_close($ch);
$msg = $this->_read_message($response);
var_dump($msg);