Answer the question
In order to leave comments, you need to log in
GOST signature in php or how to sign SOAP GOST algorithms?
Added to OpenSSL GOST Engine, checked
[email protected]:/$ openssl ciphers|tr ':' '\n'|grep GOST
GOST2012-GOST8912-GOST8912
GOST2001-GOST89-GOST89
--with-system-ciphers --with-openssl
Array
(
[0] => GOST 28147-89 MAC
[1] => GOST R 34.11-2012 with 256 bit hash
[2] => GOST R 34.11-2012 with 512 bit hash
[3] => GOST R 34.11-94
[4] => blake2b512
[5] => blake2s256
[6] => gost-mac
[7] => gost-mac-12
[8] => md4
[9] => md5
[10] => md5-sha1
[11] => md_gost12_256
[12] => md_gost12_512
[13] => md_gost94
[14] => ripemd160
[15] => sha1
[16] => sha224
[17] => sha256
[18] => sha3-224
[19] => sha3-256
[20] => sha3-384
[21] => sha3-512
[22] => sha384
[23] => sha512
[24] => sha512-224
[25] => sha512-256
[26] => shake128
[27] => shake256
[28] => sm3
[29] => whirlpool
)
openssl req -newkey gost2012_256 -pkeyopt paramset:A -out cert.csr -keyout key.pem
openssl x509 -req -in cert.csr -out cert.pem -signkey key.pem -days 730
<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
$sert = 'file://' . __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'cert.pem';
$private = 'file://' . __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'certs' . DIRECTORY_SEPARATOR . 'key.pem';
$data = 'test string test string test string test string';
openssl_sign($data, $sign, openssl_get_privatekey($private, '123456'), 'md_gost12_256');
var_dump(base64_encode($sign));
while ($msg = openssl_error_string())
echo $msg . "<br />\n";
?>
Warning: openssl_sign(): key type not supported in this PHP build! in /home/adminka/callbacksoap/test.php on line 11
string(88) "xlRC/hbqWkqDb/ENW0QlvWC/Bx9pqZfr6hEZvA9ZazLKVE7rjIWwWciVFU8xPKH0MKmfHKltouC5xk32GZ3Erg=="
<ds:SignatureValue></ds:SignatureValue>
. The test self-signed certificate in production must be replaced by the certificate confirmed in the CA.
Answer the question
In order to leave comments, you need to log in
Nothing happened with OpenSSL. Made with CryptoPRO. Put CSP on the server, installed certificates and built the phpcades extension. Below is shitty code, links to examples and instructions.
<?php
namespace PHPCadesSOAP;
use CPStore;
class CryptoPro {
public static function SetupStore($location, $name, $mode) {
$store = new CPStore();
$store->Open($location, $name, $mode);
return $store;
}
public static function SetupCertificates($location, $name, $mode) {
$store = self::SetupStore($location, $name, $mode);
return $store->get_Certificates();
}
public static function SetupCertificate($location, $name, $mode, $find_type, $query, $valid_only, $number) {
$certs = self::SetupCertificates($location, $name, $mode);
if ($find_type != NULL) {
$certs = $certs->Find($find_type, $query, $valid_only);
if (is_string($certs))
return $certs;
else
return $certs->Item($number);
}
else {
$cert = $certs->Item($number);
return $cert;
}
}
public static function createMessageID() {
$uuid = md5(uniqid(rand(), true));
$guid = 'uudi:' .
substr($uuid, 0, 8) . "-" .
substr($uuid, 8, 4) . "-" .
substr($uuid, 12, 4) . "-" .
substr($uuid, 16, 4) . "-" .
substr($uuid, 20, 12);
return $guid;
}
}
<?php
namespace PHPCadesSOAP;
use SoapClient;
use PHPCadesSOAP\Logger;
use DOMDocument;
use PHPCadesSOAP\CryptoPro;
use CPSigner;
use CPSignedXml;
class MySoapClient extends SoapClient {
private $certSubjectName = 'test certificate';
private $IPS_id = '********-****-****-****-************';
function __doRequest($request, $location, $saction, $version, $one_way = NULL) {
Logger::debug('Неподписанный запрос от MySoapClient - ' . $request);
$cert = CryptoPro::SetupCertificate(CURRENT_USER_STORE, "My", STORE_OPEN_READ_ONLY, CERTIFICATE_FIND_SUBJECT_NAME, $this->certSubjectName, 0, 1);
$certData = preg_replace('/\n+/', '', $cert->export(0));
$xml = new DOMDocument();
$xml->loadXML($request);
$Envelope = $xml->getElementsByTagName('Envelope')->item(0);
$Body = $Envelope->getElementsByTagName('Body')->item(0);
$prefix = $Envelope->prefix;
$Envelope->setAttribute('xmlns:wsse', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd');
$Envelope->setAttribute('xmlns:wsu', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd');
$Envelope->setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#');
$Envelope->setAttribute('xmlns:a', 'http://www.w3.org/2005/08/addressing');
$Header = $xml->createElement($prefix . ':Header');
$To = $xml->createElement('a:To', 'https://**********************');
$Action = $xml->createElement('a:Action', 'sendResponse');
$ReplyTo = $xml->createElement('a:ReplyTo');
$ReplyToAddress = $xml->createElement('a:Address', 'http://www.w3.org/2005/08/addressing/anonymous');
$FaultTo = $xml->createElement('a:FaultTo');
$FaultToAddress = $xml->createElement('a:Address', 'http://www.w3.org/2005/08/addressing/anonymous');
$MessageID = $xml->createElement('a:MessageID', CryptoPro::createMessageID());
$Security = $xml->createElement('wsse:Security');
$BinarySecurityToken = $xml->createElement('wsse:BinarySecurityToken', $certData);
$BinarySecurityToken->setAttribute('EncodingType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary');
$BinarySecurityToken->setAttribute('ValueType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3');
$bsd_id = uniqid('x509-');
$BinarySecurityToken->setAttribute('wsu:Id', $bsd_id);
$Signature = $xml->createElement('ds:Signature');
$SignedInfo = $xml->createElement('ds:SignedInfo');
$CanonicalizationMethod = $xml->createElement('ds:CanonicalizationMethod');
$CanonicalizationMethod->setAttribute('Algorithm', 'http://www.w3.org/2001/10/xml-exc-c14n#');
$SignatureMethod = $xml->createElement('ds:SignatureMethod');
$SignatureMethod->setAttribute('Algorithm', 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256');
$Reference_of_body = $xml->createElement('ds:Reference');
$uri_on_body = uniqid('body-');
$Reference_of_body->setAttribute('URI', '#' . $uri_on_body);
$Body->setAttribute('wsu:Id', $uri_on_body);
$Reference_of_body_Transforms = $xml->createElement('ds:Transforms');
$Reference_of_body_Transforms_Transform = $xml->createElement('ds:Transform');
$Reference_of_body_Transforms_Transform->setAttribute('Algorithm', 'http://www.w3.org/2001/10/xml-exc-c14n#');
$Reference_of_body_DigestMethod = $xml->createElement('ds:DigestMethod');
$Reference_of_body_DigestMethod->setAttribute('Algorithm', 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256');
$Reference_of_body_DigestValue = $xml->createElement('ds:DigestValue');
$SignatureValue = $xml->createElement('ds:SignatureValue');
$KeyInfo = $xml->createElement('ds:KeyInfo');
$SecurityTokenReference = $xml->createElement('wsse:SecurityTokenReference');
$SecurityTokenReference_Reference = $xml->createElement('wsse:Reference');
$SecurityTokenReference_Reference->setAttribute('ValueType', "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
$SecurityTokenReference_Reference->setAttribute('URI', '#' . $bsd_id);
$Envelope->insertBefore($Header, $Body);
$Header->appendChild($To);
$Header->appendChild($Action);
$Header->appendChild($ReplyTo);
$ReplyTo->appendChild($ReplyToAddress);
$Header->appendChild($FaultTo);
$FaultTo->appendChild($FaultToAddress);
$Header->appendChild($MessageID);
$Header->appendChild($Security);
$Security->appendChild($BinarySecurityToken);
$Security->appendChild($Signature);
$Signature->appendChild($SignedInfo);
$SignedInfo->appendChild($CanonicalizationMethod);
$SignedInfo->appendChild($SignatureMethod);
$SignedInfo->appendChild($Reference_of_body);
$Reference_of_body->appendChild($Reference_of_body_Transforms);
$Reference_of_body_Transforms->appendChild($Reference_of_body_Transforms_Transform);
$Reference_of_body->appendChild($Reference_of_body_DigestMethod);
$Reference_of_body->appendChild($Reference_of_body_DigestValue);
$Signature->appendChild($SignatureValue);
$Signature->appendChild($KeyInfo);
$KeyInfo->appendChild($SecurityTokenReference);
$SecurityTokenReference->appendChild($SecurityTokenReference_Reference);
$request = $xml->saveXML();
$signer = new CPSigner();
$signer->set_Certificate($cert);
$signer->set_Options(2);
$sd = new CPSignedXml();
$sd->set_SignatureType(2);
$sd->set_Content($request);
$sd->set_DigestMethod('urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-512');
$sd->set_SignatureMethod('urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-512');
$signedXml = $sd->Sign($signer, "//*[local-name()='Signature']");
Logger::debug('подписанный запрос от MySoapClient - ' . $signedXml);
return parent::__doRequest($signedXml, $location, $saction, $version);
}
}
<?php
$xml = file_get_contents('/var/www/dsig.xml');
try {
$xpath = "//*[local-name()='Signature' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']";
$xmldsig = new CPSignedXML();
$xmldsig->Verify($xml, $xpath);
print("OK\n");
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question