Подписать отправляемый XML с помощью ЭЦП
Я нашел вот эту инструкцию, но не могу его реализовать на C#.
Необходимо выполнить следующие действия:
- Создать XML, используя XSD схему для подписываемых данных (Схему можно получить перейдя по ссылке http://esf.gov.kz:8080/esf-web/ws/EsfXsdService?wsdl);
- Убрать XML заголовок (строку вида
<?xml version="1.0"?>)- Убрать все символы между XML тэгами (включая пробелы, табуляции и символы перевода строки);
- Подписываемые данные должны начинаться с тега
<invoice>и заканчиваться тегом</invoice>, исключая неймспейсы и префиксы.
Пример:<invoice> <date>04.08.2016</date> <invoiceType>ORDINARY_INVOICE</invoiceType> <num>11111111111111121</num> <operatorFullname>Идрисов Кайрат Ерикович</operatorFullname> <signatureType>COMPANY</signatureType> <customers> <customer> <address>г.Астана, ул. Мира д 24 кв 12</address> <name>ТОО "АСЕМ-2"</name> <statuses> <status>NONRESIDENT</status> </statuses> </customer> </customers> <productSet> <currencyCode>KZT</currencyCode> <product> <description>цемент</description> <ndsAmount>0</ndsAmount> <priceWithTax>2500</priceWithTax> <priceWithoutTax>2500</priceWithoutTax> <quantity>5</quantity> <turnoverSize>2500</turnoverSize> <unitNomenclature>тонна</unitNomenclature> <unitPrice>500</unitPrice> </product> <product> <description>доставка</description> <ndsAmount>0</ndsAmount> <priceWithTax>8000</priceWithTax> <priceWithoutTax>8000</priceWithoutTax> <quantity>1</quantity> <turnoverSize>8000</turnoverSize> <unitNomenclature>услуга</unitNomenclature> <unitPrice>8000</unitPrice> </product> <totalExciseAmount>0</totalExciseAmount> <totalNdsAmount>0</totalNdsAmount> <totalPriceWithTax>10500</totalPriceWithTax> <totalPriceWithoutTax>10500</totalPriceWithoutTax> <totalTurnoverSize>10500</totalTurnoverSize> </productSet> <sellers> <seller> <bank>аТФ БАНК</bank> <bik>KZKS456J</bik> <iik>KZ012565854HG456253658FG</iik> <kbe>19</kbe> <name>ИП"Кайрат"</name> <statuses> <status>EXPORTER</status> </statuses> <tin>123456789011</tin> </seller> </sellers> <turnoverDate>20.07.2016</turnoverDate> </invoice>Для формирования ЭЦП для ЭСФ, Вам необходимо скачать комплект разработчика SDK по адресу http://kgd.gov.kz/ru/content/api-interfeys-1
- Используя локальный сервис(generateSignature в SDK) получить подпись для нужного ЭСФ.
- Подписать ЭСФ полученной от локального сервиса подписью.
Если Вы хотите реализовать генерацию подписи программным путем, просим выполнить следующие пункты:
- Полученную в результате выполнения шагов 2-4 канонизированную строку необходимо подписать закрытым ключом:
byte[] signature = sign(data.getBytes(StandardCharsets.UTF_8), privateKey);
- Полученный в результате подписания байтовый массив, т.е. подпись, необходимо преобразовать в base64-строку:
String signatureBase64Type = Base64.getEncoder().encodeToString(byte[] signature);
- Вставить полученную подпись(signatureBase64Type) в теги запроса веб-сервиса.
ВАЖНО! Уважаемые разработчики, обратите внимание на реализацию шагов 7 и 8 в вашей системе, так как в большинстве случаев причиной проблемы было именно отсутствие преобразования байтового массива в base64-строку.
Верификацию полученной подписи можете осуществить следующим образом:
X509Certificate cert = сертификат подписи пользователя; Signature s = Signature.getInstance(cert.getPublicKey().getAlgorithm()); s.initVerify(cert.getPublicKey()); s.update(invoiceXmlString.getBytes(StandardCharsets.UTF_8)); boolean signatureVerificationResult = s.verify(Base64.getDecoder().decode(signature));
пока что нашел кода для получения certificate
// получение данные для certificate
try
{
X509Certificate2 cert = new X509Certificate2("key path.p12", "password", X509KeyStorageFlags.PersistKeySet);
byte[] signature = cert.GetRawCertData();
String signatureBase64Type = Convert.ToBase64String(signature);
Console.WriteLine(signatureBase64Type);
}
catch (CryptographicException ex)
{
Console.WriteLine("Ошибка: {0}", ex.Message);
}
как я могу получить код для signature ?
Ответы (1 шт):
- Для начала пойми в каком виде / формате / контейнере у тебя хранится сертификат/открытый/закрытый ключи?
- Есть весь сертификат или только открытая его часть? Обычно открытая часть передается вместе с подписью.
- Тебе нужно только проверять подпись или подписывать тоже необходимо?
- Какой используется крипто-провайдер. RSA или что-то другое? если нужна совместимость с Java ( а исходники в описании на ней приведены ) то смотри в сторону сборки Org.BouncyCastle для .NET, я с ее помощью пробовал реализовать RSA256 для авторизации JWT в Google FCM, более ничего в дотнете с PEM-форматом сертификата нормально не работало.