03.12.2004 10:03:57Trial CryptoPro & CAPICOM Ответов: 7
Vlad
Пытаюсь подписать данные при помощи SignedData.Sign в VB с установленным CryptoPro (30 дневная версия).Под WinXP выдается ошибка OC "Application error...". Под Win2003Datacenter процесс просто бесследно исчезает. Связано ли это с тем, что версия CryptoPro триальная ?

Message = SignedData.Sign(Signer, False)


 
Ответы:
03.12.2004 11:43:57mAxDM
вряд ли
03.12.2004 12:22:28Vlad
Спасибо.
У кого нибудь есть идеи с чем это может быть связано...
03.12.2004 13:14:29mAxDM
Какая ошибка выдается? И можно было бы показать кусок кода.
03.12.2004 14:03:31Vlad
const SHA1 = "<some sha>"

function DoSign(text as string) as string

on error goto err

Dim message
Dim signedData

dim Signer
dim store
Dim Certs

Set Signer = CreateObject("CAPICOM.Signer")

Set Store = CreateObject("CAPICOM.Store")

StoreLocation = CAPICOM_CURRENT_USER_STORE
StoreName = "MY"

Store.Open StoreLocation, StoreName

&rsquo; Find certificate(s) matching the search criteria, if requested.
Set Certs = Store.Certificates

If Certs.Count > 0 Then
Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, SHA1)
End If

Signer.Certificate = Certificates(1)


Set signedData = CreateObject("CAPICOM.SignedData")

signedData.content = text

message = signedData.Sign(Signer, False) &rsquo; при вызове этого метода приложение падает.

DoSign = message
exit function

err:
&rsquo; поток исполнение не доходит до этого места

MsgBox err.Description
end function

"Процесс падает" значит, что либо процесс исчезает без всяких сообщений, либо виндовое окошко "Application has encountered a problem....". Никаких других собщений об ошибках не выдается, исключения в VB не ловятся.
03.12.2004 18:46:51mAxDM
А у сертификату соответствует закрытый ключ?
Certificates.Find(CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, CAPICOM_PROPID_KEY_PROV_INFO)
03.12.2004 18:55:06mAxDM
Вот работающий пример

&rsquo; Copyright(C) 2000-2001 Проект ИОК
&rsquo;
&rsquo; Этот файл содержит информацию, являющуюся
&rsquo; собственностью компании Крипто Про.
&rsquo;
&rsquo; Любая часть этого файла не может быть скопирована,
&rsquo; исправлена, переведена на другие языки,
&rsquo; локализована или модифицирована любым способом,
&rsquo; откомпилирована, передана по сети с или на
&rsquo; любую компьютерную систему без предварительного
&rsquo; заключения соглашения с компанией Крипто Про.
&rsquo;
&rsquo; Программный код, содержащийся в этом файле, предназначен
&rsquo; исключительно для целей обучения и не может быть использован
&rsquo; для защиты информации.
&rsquo;
&rsquo; Компания Крипто-Про не несет никакой
&rsquo; ответственности за функционирование этого кода.
&rsquo;
&rsquo;-----------------------------------------------------------------------------
&rsquo;
&rsquo; В данном script-примере осуществляется подпись и проверка подписи
&rsquo; содержимого файла при помощи инструментария CAPICOM.
&rsquo;
&rsquo;******************************************************************************

Option Explicit

Const ForReading = 1, ForWriting = 2


&rsquo; Команды.
Const Unknown = 0
Const Sign = 1
Const CoSign = 2
Const Verify = 3

&rsquo; CAPICOM константы.
Const CAPICOM_CURRENT_USER_STORE = 2

Const CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6
Const CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9

Const CAPICOM_VERIFY_SIGNATURE_ONLY = 0

Const CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT = 0

Const CAPICOM_PROPID_KEY_PROV_INFO = 2

&rsquo; Аргументы командной строки.
Dim Command : Command = Unknown
Dim StoreLocation : StoreLocation = Null
Dim VerifyFlag : VerifyFlag = CAPICOM_VERIFY_SIGNATURE_ONLY
Dim IncludeOption : IncludeOption = CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
Dim bDetached : bDetached = False

&rsquo; Фильтр.
Dim FileNames()

&rsquo; В первую очередь осуществляется проверка того, что script выполняется при помощи CScript.exe.
If InStr(1, UCase(Wscript.FullName), "CSCRIPT.EXE", vbTextCompare) = 0 Then
Wscript.Echo "This script can only be executed by CScript.exe." & vbCRLF & vbCRLF &_
"You can either:" & vbCRLF & vbCRLF & _
"1. Set CScript.exe as the default (Run CScript //h:cscript), or" & vbCRLF & _
"2. Run CScript.exe directly as in, CScript " & Wscript.ScriptName & "."
Wscript.Quit(-1)
End If

&rsquo; Разбор командной сроки.
ParseCommandLine

&rsquo; Поиск сертификата, на котором будет осуществляться операция подписи.
Dim Signer
Set Signer = CreateObject("CAPICOM.Signer")

&rsquo; Определение свойств операции подписи.
If Command = Sign OR Command = CoSign Then
Dim iIndex
Dim Store
Dim Certificates
Dim StoreName : StoreName = "MY"

&rsquo; Открытие соответствующего хранилища.
Set Store = CreateObject("CAPICOM.Store")

StoreLocation = CAPICOM_CURRENT_USER_STORE

Store.Open StoreLocation, StoreName

&rsquo; В качестве кандитатов на сертификат, на котором будет осуществлена подпись,
&rsquo; изначально определяются все сертификаты хранилища.
Set Certificates = Store.Certificates

&rsquo; Из них не рассматриваются сертификаты, в которых отсутствует закрытый ключ.
If Certificates.Count > 0 Then
Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, CAPICOM_PROPID_KEY_PROV_INFO)
End If

&rsquo; Из них выбираются только сертификаты, действительные в настоящее время.
If Certificates.Count > 0 Then
Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID, Now)
End If

&rsquo; Выбор сертификата для подписи. Если после проведенной фильтрации осталось несколько кандидатов,
&rsquo; то пользователю предоставляется выбор одного из них (при помощи диалогового окна).
Select Case Certificates.Count
Case 0
Wscript.Stdout.Writeline "Error: No signing certificate can be found."
Wscript.Quit(1)

Case 1
Signer.Certificate = Certificates(1)

Case Else
Set Certificates = Certificates.Select("CSignData.vbs", "Please select a certificate to sign " & FileNames(0) & ".")
If Certificates.Count = 0 Then
Wscript.Stdout.Writeline "Error: Certificate selection dialog was cancelled."
Wscript.Quit(2)
End If
Signer.Certificate = Certificates(1)

End Select

Set Certificates = Nothing
Set Store = Nothing

Signer.Options = IncludeOption

End If

&rsquo; Выполнение требуемой операции.
Select Case Command
Case Sign
DoSignCommand FileNames, bDetached, Signer

Case CoSign
DoCoSignCommand FileNames, bDetached, Signer

Case Verify
DoVerifyCommand FileNames, bDetached, VerifyFlag

End Select

&rsquo; Освобождение ресурсов.
Set Signer = Nothing

Wscript.Quit(0)

&rsquo; Конец main


&rsquo;******************************************************************************
&rsquo; Функиция DoSignCommand подписывает содержимое файла FileNames(0)
&rsquo; и записывает подписанные данные в FileNames(1).
&rsquo;******************************************************************************

Sub DoSignCommand (FileNames, bDetached, Signer)
Dim Content
Dim Message
Dim SignedData

&rsquo; Создание объекта SignedData.
Set SignedData = CreateObject("CAPICOM.SignedData")

&rsquo; Распечатка информативного сообщения.
Wscript.Stdout.Writeline "Signing text file " & FileNames(0) & "."
Wscript.Stdout.Writeline

&rsquo; Загрузка содержимого файла для подписи.
LoadFile FileNames(0), Content

&rsquo; Подпись.
SignedData.Content = Content
Message = SignedData.Sign(Signer, bDetached)

&rsquo; Сохранение подписанных данных в FileNames(1).
SaveFile FileNames(1), Message
Wscript.Stdout.Writeline "Successful - Signed message saved to " & FileNames(1) & "."

&rsquo; Освобождение ресурсов.
Set SignedData = Nothing

End Sub &rsquo;Конец DoSignCommand


&rsquo;******************************************************************************
&rsquo; Функция DoCoSignCommand подписывает текстовый файл FileNames(0)и сохраняет
&rsquo; заново подписанное содержимое в FileNames(1).
&rsquo;******************************************************************************

Sub DoCoSignCommand (FileNames, bDetached, Signer)
Dim Content
Dim Message
Dim SignedData

&rsquo; Создание объекта SignedData.
Set SignedData = CreateObject("CAPICOM.SignedData")

&rsquo; Распечатка информативного сообщения.
Wscript.Stdout.Writeline "CoSigning text file " & FileNames(0) & "."
Wscript.Stdout.Writeline


&rsquo; Загрузка подписанных данных.
LoadFile FileNames(0), Message

&rsquo; Проверка подписанных данных.
SignedData.Verify Message, bDetached, VerifyFlag

&rsquo; Повторная подпись.
Message = SignedData.CoSign(Signer, bDetached)

&rsquo; Сохранение внось подписанных данных в FileNames(0).
SaveFile FileNames(0), Message
Wscript.Stdout.Writeline "Successful - CoSigned message saved to " & FileNames(0) & "."

&rsquo; Освобождение ресурсов.
Set SignedData = Nothing

End Sub &rsquo; Конец DoCoSignCommand


&rsquo;******************************************************************************
&rsquo; Функция DoVerifyCommand проверяется подписанный текстовый файл.
&rsquo;******************************************************************************

Sub DoVerifyCommand (FileNames, bDetached, VerifyFlag)
Dim Content
Dim Message
Dim SignedData

&rsquo; Создание объекта SignedData.
Set SignedData = CreateObject("CAPICOM.SignedData")

&rsquo; Распечатка информативного сообщения.
Wscript.Stdout.Writeline "Verifying signed text file " & FileNames(0) & ", please wait..."
Wscript.Stdout.Writeline

&rsquo; Загрузка подписанных данных для проверки.
LoadFile FileNames(0), Message


&rsquo; Проверка подписи.
SignedData.Verify Message, bDetached, VerifyFlag


&rsquo; Сохранение проверенного содержимого в FileNames(1).
SaveFile FileNames(1), SignedData.Content
Wscript.Stdout.Writeline "Successful - Verified content saved to " & FileNames(1) & "."

&rsquo; Освобождение ресурсов.
Set SignedData = Nothing

End Sub &rsquo; Конец DoVerifyCommand

&rsquo;******************************************************************************
&rsquo;Функция LoadFile читает содержимое текстового файла.
&rsquo;******************************************************************************

Sub LoadFile (FileName, Buffer)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

If Not fso.FileExists(FileName) Then
Wscript.Stdout.Writeline "Error: File " & FileName & " not found."
Wscript.Quit(-5)
End If

Dim ts
Set ts = fso.OpenTextFile(FileName, ForReading)
Buffer = ts.ReadAll

End Sub &rsquo; Конец LoadFile


&rsquo;******************************************************************************
&rsquo; Функция SaveFile сохраняет строку в файл.
&rsquo;******************************************************************************

Sub SaveFile (FileName, Buffer)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim ts
Set ts = fso.OpenTextFile(FileName, ForWriting, True)
ts.Write Buffer

End Sub &rsquo; Конец SaveFile


&rsquo;******************************************************************************
&rsquo; Функция ParseCommandLine разбирает командную строку и устанавливает
&rsquo; опции согласно ей.
&rsquo;******************************************************************************

Sub ParseCommandLine

&rsquo; Константы для разбора состояний, задаваемых командной строкой.
Const ARG_STATE_COMMAND = 0
Const ARG_STATE_OPTIONS = 1
Const ARG_STATE_FILENAME = 13

&rsquo; Разбор командной строки.
Dim Arg
Dim ArgState : ArgState = ARG_STATE_COMMAND

For Each Arg In Wscript.Arguments
Select Case ArgState
Case ARG_STATE_COMMAND
Select Case UCase(Arg)
Case "SIGN"
Command = Sign

Case "COSIGN"
Command = CoSign

Case "VERIFY"
Command = Verify

Case Else
DisplayUsage

End Select

ArgState = ARG_STATE_OPTIONS

Case ARG_STATE_OPTIONS
Select Case UCase(Arg)
Case "-?", "/?"
DisplayUsage

Case Else
If Left(Arg, 1) = "-" OR Left(Arg, 1) = "/" Then
DisplayUsage
Else
ReDim FileNames(0)
FileNames(0) = Arg
End If
ArgState = ARG_STATE_FILENAME

End Select

Case ARG_STATE_FILENAME
If Left(Arg, 1) = "-" OR Left(Arg, 1) = "/" Then
DisplayUsage
Else
ReDim Preserve FileNames(UBound(FileNames) + 1)
End If
FileNames(UBound(FileNames)) = Arg

Case Else
Wscript.Stdout.Writeline "Internal script error: Unknown argument state (" & CStr(ArgState) & ") encountered."
Wscript.Quit(-3)

End Select
Next

&rsquo; Проверка правильности состояния.
If ArgState <> ARG_STATE_FILENAME Then
DisplayUsage
End If

&rsquo; Проверка опций.
Select Case Command
Case Sign
&rsquo; Функция подписи должна иметь входной и выходной файлы.
If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
DisplayUsage
End If


Case Verify
&rsquo; Функция проверки подписи должна иметь входной и выходной файлы.
If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
DisplayUsage
End If

End Select

End Sub &rsquo; Конец ParseCommandLine


&rsquo;******************************************************************************
&rsquo; Функция DisplayUsage распечатывает информацию об использовании данного
&rsquo; примера, и затем осуществляет выход с ошибкой.
&rsquo;******************************************************************************

Sub DisplayUsage

Select Case Command
Case Unknown
Wscript.Stdout.Writeline "Usage: CSignData Command [Options] File1 [File2]"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Command:"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " Sign -- Sign a text file"
Wscript.Stdout.Writeline " CoSign -- CoSign a signed text file"
Wscript.Stdout.Writeline " Verify -- Verify a signed text file"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "For help on a specific command, enter ""CSignData Command -?"""

Case Sign
Wscript.Stdout.Writeline "Usage: CSignData Sign [Options] ContentFile SignedFile"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "The Sign command is used to sign a text file. Signing protects a file from"
Wscript.Stdout.Writeline "tampering, and allows user to verify the signer based on signing certificate."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "For non-detached signing, both the content and signature will be saved to"
Wscript.Stdout.Writeline "SignedFile. For detached signing, only the signature is saved to SignedFile."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Options:"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " -? -- This help screen"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " ContentFile -- Text file to be signed"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " SignedFile -- Signed file (contains signature only if detached)"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored,"
Wscript.Stdout.Writeline " and the ** symbol indicates option can be listed multiple times."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " If there is only one certificate found in the MY store or PFX that"
Wscript.Stdout.Writeline " matches the requirement, that particular certificate will be used."
Wscript.Stdout.Writeline " However, if there is more than one certificate matching the requirement,"
Wscript.Stdout.Writeline " a dialog will be displayed to allow selection of the signing certificate."
Wscript.Stdout.Writeline

Case CoSign
Wscript.Stdout.Writeline "Usage: CSignData CoSign [Options] SignedFile [ContentFile]"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "The CoSign command is used to cosign a signed text file. CoSigning provides the"
Wscript.Stdout.Writeline "same type of benefits as signing, with an additional signature."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "For non-detached cosigning, both the content and signatures will be saved to"
Wscript.Stdout.Writeline "SignedFile. For detached cosigning, only the signatures are saved to"
Wscript.Stdout.Writeline "SignedFile."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Options:"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " -? -- This help screen"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " SignedFile -- Signed file (contains signature only if detached)"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " ContentFile -- Text file (required if detached)"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored,"
Wscript.Stdout.Writeline " and the ** symbol indicates option can be listed multiple times."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " If there is only one certificate found in the MY store or PFX that"
Wscript.Stdout.Writeline " matches the requirement, that particular certificate will be used."
Wscript.Stdout.Writeline " However, if there is more than one certificate matching the requirement,"
Wscript.Stdout.Writeline " a dialog will be displayed to allow selection of the signing certificate."
Wscript.Stdout.Writeline

Case Verify
Wscript.Stdout.Writeline "Usage: CSignData Verify [Options] SignedFile ContentFile"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "The Verify command is used to verify signed text file. Verification checks"
Wscript.Stdout.Writeline "integrity of the signed file and determines if the signing certificate is"
Wscript.Stdout.Writeline "valid and issued by a trusted party."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "For non-detached signed file, the content will be extracted and saved to"
Wscript.Stdout.Writeline "ContentFile. For detached signed file, the ContentFile is not modified."
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Options:"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " -? -- This help screen"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " SignedFile -- Signed file (contains signature only if detached)"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline " ContentFile -- Text file (will not be over written if detached)"
Wscript.Stdout.Writeline
Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored."
Wscript.Stdout.Writeline

Case Else
Wscript.Stdout.Writeline "Internal script error: Unknown help state (Command = " & CStr(Command) & ")."
Wscript.Quit(-2)

End Select

Wscript.Quit(-1)

End Sub &rsquo; Конец DisplayUsage

03.12.2004 19:09:57Vlad
Всем спасибо. Все зло было в SP2