Отправить http запрос подписанный с помощью X509Certificate - C#

Узнай цену своей работы

Формулировка задачи:

Добрый вечер. Возникла задача, которую даже не знаю как теоретически решить. Имеем: Сайт с авторизацией через сертификат JavaScript код на странице этого сайта. Одна из функций подписывает(цифровая подпись) XML данные и Submit'ит форму. Подпись ставится на основании выбираемого сертификата. Вызывается функция при нажатии на кнопку:
<INPUT id=ctl01_ctl01_btnSign onclick="esign(); __doPostBack('ctl01$ctl01$btnSign','')" name=ctl01$ctl01$btnSign value=Подписать type=button>
function  esign()
{
    //КОНСТАНТЫ
    STORE_LOCATION = 2;
    STORE_NAME = "My";
    //UserObjectID в конфигурации сервера
    dsigObjectId = new String("TS_SO_Zayavka_polzovatelya");
    
    //Инициализация active-x объектов (msxml)
    try {
        xmldoc = new ActiveXObject("MSXML2.DOMDocument.5.0");
        xmldoce = new ActiveXObject("MSXML2.DOMDocument.5.0");
        xmldsig = new ActiveXObject("Msxml2.MXDigitalSignature.5.0");
    }
    catch (Exception) {
        alert(Exception.message);
        alert("Невозможно загрузить ActiveXObject MSXML2");
        return null;
    }
    
    //Инициализация active-x объектов (capicom)
    try
    {
    oStore = new ActiveXObject("CAPICOM.Store.2");
    oCerts = new ActiveXObject("CAPICOM.Certificates");
    oSigner = new ActiveXObject("CAPICOM.Signer");
    }
    catch(Exception)
    {
alert(Exception.message);
    alert("Невозможно загрузить ActiveXObject CAPICOM");
        return null;
    }
    //Текст заявки
    //text = build_xhtml();
    xmldoc.loadXML(document.getElementById('ctl01_ctl01_hdnDemandXML').value);
    //Конверт
    xmldoce.async = false;
    xmldoce.validateOnParse = false;
    xmldoce.preserveWhiteSpace = false;
    xmldoce.resolveExternals = false;
    xmldoce.loadXML("<ds:Signature xmlns:ds='http://www.w3.org/2000/09/xmldsig#'><ds:SignedInfo><ds:CanonicalizationMethod Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315'/><ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411'/><ds:Reference URI='#"+dsigObjectId+"' Type='http://www.w3.org/2000/09/xmldsig#;Object'><ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#gostr3411'/><ds:DigestValue/></ds:Reference></ds:SignedInfo><ds:SignatureValue/><ds:Object Id='"+dsigObjectId+"' MimeType='text/plain'/><ds:KeyInfo/></ds:Signature>");
    xmldoce.setProperty("SelectionNamespaces", "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'");
 
    //Размещение текста в конверт
    elmToWrap = xmldoc.documentElement.cloneNode(true);
    elmWhereTo = xmldoce.selectSingleNode("//*[@Id='" + dsigObjectId +"']");
    elmWhereTo.appendChild(elmToWrap);
    xmldoc = xmldoce;
    xmldoce = null;
 
    //Пользователь выбирает сертификат
    try
    {
        oStore.Open(STORE_LOCATION, STORE_NAME, 128);
        oCerts = oStore.Certificates;
        if (oCerts.Count == 0)
        { 
            alert("В личном хранилище нет сертификатов");
            return null;
        }
        oSelectedCerts = oCerts.Select();
        oSignerCert = oSelectedCerts(1);
    }
    catch(Exception)
    {
//      alert(Exception.description);
        alert(Exception.message);
        return null;
    }
 
    //Указатель на конверт
    xmldsig.signature = xmldoc.selectSingleNode("//*[count(ancestor::*)=0]");
    
    //Доступ к секретному ключу сертификата
    try
    {
        pKey = xmldsig.createKeyFromCSP(oSignerCert.PrivateKey.ProviderType, oSignerCert.PrivateKey.ProviderName, oSignerCert.PrivateKey.ContainerName, 0);
    }
    catch(Exception)
    {
        //alert(Exception.description);
        alert(Exception.message);
        alert("Невозможно получить доступ к секретному ключу сертификата.");
        return null;
    }
    
    //Подпись конверта
    try
    {
        pKeyOut = xmldsig.sign(pKey, 2);
    }
    catch(Exception)
    {
//      alert(Exception.description);
        alert(Exception.message);
        alert("Невозможно подписать заявку.");
        return null;
    }
 
    //Отправка заявки на сервер
    document.getElementById("ctl01_ctl01_hdnDemandSidned").value = xmldoc.xml;
    //document.getElementById("Form1").submit();
    return;
}
Необходимо: Автоматизировать выбор сертификата и подписание заявки. Я уже посмотрел какие данные отправляются при сабмите формы и попробовал отправить такой же POST-запрос через HttpWebRequest. Не помогло: ошибок нет, но данные не подписаны. Переписал JavaScript код на C#, получил идентичную подпись, но и это не помогло. Из идей осталось: 1)использовать "тяжелый" webbrowser(не понятно как использовать в нем X509Certificate) 2)выполнить просто скопированную функцию javascript, но тоже не знаю каким образом, так как она использует данные из document Буду рад, если подскажете в каком направлении двигаться.

Решение задачи: «Отправить http запрос подписанный с помощью X509Certificate»

textual
Листинг программы
var xmldoc = new DOMDocument50Class();
            var xmldoce = new DOMDocument50Class();
            var xmldsig = new MXDigitalSignature50Class();
 
            xmldoc.loadXML(requestBody);
 
            //Конверт
            xmldoce.async = false;
            xmldoce.validateOnParse = false;
            xmldoce.preserveWhiteSpace = false;
            xmldoce.resolveExternals = false;
            xmldoce.loadXML(string.Format(Signature, ObjectId));
            xmldoce.setProperty("SelectionNamespaces", "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'");
 
            //Размещение текста в конверт
            IXMLDOMNode elmToWrap = xmldoc.documentElement.cloneNode(true);
            IXMLDOMNode elmWhereTo = xmldoce.selectSingleNode("//*[@Id='" + ObjectId + "']");
            elmWhereTo.appendChild(elmToWrap);
            xmldoc = xmldoce;          
 
            //Доступ к секретному ключу сертификата
 
            IXMLDSigKey pKey = xmldsig.createKeyFromCSP(providerType, string.Empty, containerName, 0);
 
            //Подпись конверта
            xmldsig.sign(pKey, XMLDSIG_WRITEKEYINFO.CERTIFICATES);
            return xmldoc.xml;

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.8 из 5