Слава тебе! Решаю сейчас такую же задачу - надо подписывать поток ЭСФ и отправлять через Exite. Два дня мучался, переписав JS скрипт, работающий с Capicom, на .NET. То, что сделал через Capicom, файл с подписью генерировало, но провайдер отвечал, что "Подпись неверна или сертификат недействителен", хотя указанный тут инструмент проверки с госуслуг на каждый такой файл уверенно отвечал, что все отлично, выдавал список сертификатов из цепочки, но все равно дело не шло. Пока не увидел твой код - у меня были проблемы с кодировкой, которые я благодаря твоей работе решил, но Capicom со своей задачей так и не справился, поэтому переписал под Cadescom, как это сделано в твоем коде. Сейчас получил результат "Документооборот завершен", то есть, все работает абсолютно правильно. Уверен, что людей, которые испытывают трудности с решением этой задачи, масса, поэтому привожу свой код VB.NET.
P.S> Если вы скопировали код, сделали ссылку на библиотеки, но получаете исключение типа "Класс не зарегистрирован" - не спешите стучать в бубен, для начала удостоверьтесь, что ваш код компилируется в х86. Под х64 сделать вызовы к 32-разрядному COM интерфейсу библиотеки Capicom вы не сможете.
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
''''Dim store As New CAdESCOM.CPStore
''''For i = 0 To 4
''''''''Try
''''''''''''store.Open(i)
''''''''''''For Each cert As CAdESCOM.CPCertificate In store.Certificates
''''''''''''''''Dim li = lvCerts.Items.Add(i)
''''''''''''''''li.SubItems.Add(cert.SerialNumber)
''''''''''''''''li.SubItems.Add(cert.SubjectName)
''''''''''''''''li.SubItems.Add(cert.ValidToDate)
''''''''''''Next
''''''''''''store.Close()
''''''''Catch ex As Exception
''''''''End Try
''''Next
End Sub
Private Sub lvCerts_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lvCerts.SelectedIndexChanged
''''If lvCerts.SelectedItems.Count = 0 Then Exit Sub
''''txtStore.Text = lvCerts.SelectedItems(0).SubItems(0).Text
''''txtCert.Text = lvCerts.SelectedItems(0).SubItems(1).Text
End Sub
Private Sub btnOpenFile_Click(sender As Object, e As EventArgs) Handles btnOpenFile.Click
''''If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.Cancel Then Exit Sub
''''txtFile.Text = OpenFileDialog1.FileName
End Sub
Public Function FindCertificate(StoreNumber As Integer, Serial As String) As CAdESCOM.CPCertificate
''''Dim Store As New CAdESCOM.CPStore
''''Store.Open(StoreNumber)
''''For Each c In Store.Certificates
''''''''If c.SerialNumber = Serial Then
''''''''''''FindCertificate = c
''''''''''''Store.Close()
''''''''''''Exit Function
''''''''End If
''''Next
''''Store.Close()
''''Return Nothing
End Function
Public Function Sign(Cert As CAdESCOM.CPCertificate, InputFile As IO.FileInfo, OutputPath As String) As Boolean
''''Try
''''''''Dim Signer As New CAdESCOM.CPSigner
''''''''Signer.Certificate = Cert
''''''''Signer.Options = CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY 'Включать только сертификат субъекта
''''''''Dim Signed As New CAdESCOM.CadesSignedData
''''''''Signed.ContentEncoding = CADESCOM_CONTENT_ENCODING_TYPE.CADESCOM_BASE64_TO_BINARY
''''''''Dim FileContent = IO.File.ReadAllText(InputFile.FullName, Encoding.Default)
''''''''Signed.Content = Convert.ToBase64String(Encoding.Default.GetBytes(FileContent))
''''''''Dim SignedContent = Signed.SignCades(Signer, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, True, CAdESCOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64)
''''''''IO.File.WriteAllText(OutputPath, SignedContent)
''''''''Sign = True
''''Catch ex As Exception
''''''''Sign = False
''''End Try
End Function
Private Sub btnSign_Click(sender As Object, e As EventArgs) Handles btnSign.Click
''''Dim cert = FindCertificate(txtStore.Text, txtCert.Text)
''''If cert Is Nothing Then
''''''''MsgBox("Сертификат не найден")
''''Else
''''''''Dim file = New IO.FileInfo(txtFile.Text)
''''''''If file.Exists Then
''''''''''''Dim BinPath = file.DirectoryName & file.Name.Substring(0, file.Name.LastIndexOf(".")) & ".bin"
''''''''''''If My.Computer.FileSystem.FileExists(BinPath) Then My.Computer.FileSystem.DeleteFile(BinPath)
''''''''''''MsgBox("Результат: " & Sign(cert, file, BinPath))
''''''''Else
''''''''''''MsgBox("Файл для подписи не обнаружен", MsgBoxStyle.Critical)
''''''''End If
''''End If
End Sub
Отредактировано пользователем 2 декабря 2016 г. 23:37:53(UTC)
| Причина: Не указана