| ||||
| ||||
Использует ли кто либо связку capicom + perl? Может кто наступал уже на эти грабли? в perl использую следующую конструкцию my $Signer = Win32::OLE->new('CAPICOM.Signer') or die "Oops, cannot start CAPICOM.Signer"; my $Store = Win32::OLE->new('CAPICOM.Store') or die "Oops, cannot start CAPICOM"; my $SignedData = Win32::OLE->new('CAPICOM.SignedData') or die "Oops, cannot start CAPICOM.SignedData"; # поиск сертификата для подписи я опускаю ибо работает без проблем my $Content = 'Текст для подписи'; my $MyMail = MIME::Entity->build( From => 'frommail@mymail.ru', To => 'tomail@mymail.ru', Subject => "Test crypto", Type => 'multipart/signed; protocol="application/pkcs7-signature"', ); $MyMail->attach( Data => "$Content", Type => "text/plain", Encoding => "quoted-printable" ); my $ContentToSign = $MyMail->parts(0)->stringify; $SignedData->LetProperty('Content',$ContentToSign); my $Message = $SignedData->Sign($Signer, 1,CAPICOM_ENCODE_BASE64); $MyMail->attach( Data => decode_base64($Message), Type => 'application/pkcs7-signature', Name => 'smime.p7s', Disposition => 'attachment', Filename => 'smime.p7s', Description => 'S/MIME Cryptographic Signature', Encoding => "base64" ); my $smtp = Net::SMTP->new('mail.mymail.ru',Timeout => 30); $smtp->mail('frommail@mymail.ru'); $smtp->recipient('tomail@mymail.ru'); $smtp->data; $smtp->datasend($MyMail->stringify); $smtp->dataend; $smtp->close; при получении письма неправильная подпись. может кто подскажет, какие особенности параметра Content? Что именно туда должно попасть? в примерах для VB постоянно присутствует oSignedData.Content = StrConv(strContent, vbFromUnicode) но перл с юникодом и не работет. | ||||
Ответы: | ||||
| ||||
Зато CAPICOM работает. Свойство Content ожидает юникодную строку (BSTR). Как осуществляет преобразование метод LetProperty - делает неявное преобразование ANSI-Unicode или копирует как последовательность байт? В дельфи и некоторых классах С++ как раз имеет место быть такое неявное преобразование например. | ||||
| ||||
Самое интересное, что средствами capicom эти сообщения распознаются, как подписанные не зависимо от конвертирования Content в BSTR, а почтовиками нет. Что же он подписывает? | ||||
| ||||
Сделайте присоединенную подпись и посмотрите | ||||
| ||||
Вы правы. Все так и было. Исходный текст был в юникоде. Преобразование помогло. | ||||
| ||||
а как преобразовать ? первый раз пытаюсь что то сделать на perl спасибо | ||||
| ||||
Пример создания и отправки письма с двумя подписями на перл для Windows. #!/usr/bin/perl -w use strict; use WIN32::OLE; use Win32::OLE::Variant; use warnings; use NET::SMTP; use MIME::Entity; use MIME::Base64; use Encode; # CAPICOM constant definitions use constant { Unknown => 0, Sign => 1, Timestamp => 2, Verify => 3, CAPICOM_LOCAL_MACHINE_STORE => 1, CAPICOM_CURRENT_USER_STORE => 2, CAPICOM_ACTIVE_DIRECTORY_USER_STORE => 3, CAPICOM_SMART_CARD_USER_STORE => 4, CAPICOM_CERTIFICATE_FIND_SHA1_HASH => 0, CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME => 1, CAPICOM_CERTIFICATE_FIND_ISSUER_NAME => 2, CAPICOM_CERTIFICATE_FIND_ROOT_NAME => 3, CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME => 4, CAPICOM_CERTIFICATE_FIND_EXTENSION => 5, CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY => 6, CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY => 7, CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY => 8, CAPICOM_CERTIFICATE_FIND_TIME_VALID => 9, CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID => 10, CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED => 11, CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT => 0, CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN => 1, CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY => 2, CAPICOM_VERIFY_SIGNATURE_ONLY => 0, CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE => 1, CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME => 0, CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME => 1, CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION => 2, CAPICOM_PROPID_KEY_PROV_INFO => 2, CAPICOM_LOCAL_MACHINE_STORE => 1, CAPICOM_CURRENT_USER_STORE => 2, CAPICOM_STORE_OPEN_READ_ONLY => 0, CAPICOM_KEY_STORAGE_DEFAULT => 0, CAPICOM_ENCODE_ANY => 0xffffffff, CAPICOM_ENCODE_BASE64 => 0, CAPICOM_ENCODE_BINARY => 1, }; my $StoreLocation; my $DocName = 'test.txt'; Win32::OLE->Option ('Warn' => 3); my $Signer = Win32::OLE->new('CAPICOM.Signer') or die "Oops, cannot start CAPICOM.Signer"; my $Signer2 = Win32::OLE->new('CAPICOM.Signer') or die "Oops, cannot start CAPICOM.Signer"; my $Store = Win32::OLE->new('CAPICOM.Store') or die "Oops, cannot start CAPICOM"; my $StoreName = 'MY'; $Store->Open(CAPICOM_CURRENT_USER_STORE, $StoreName); my $Certificates = $Store->Certificates; if ($Certificates->Count > 0) { $Certificates = $Certificates->Find(CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, 'test3@test.ru'); } SWITCHCERT: { if ($Certificates->Count == 0) { print "Error! Сертификат не найден!\n"; exit; } if ($Certificates->Count == 1) { $Signer->LetProperty('Certificate',$Certificates->Item(1)); last; } print "Error! Ошибка работы с сертификатом!\n"; exit; } $Certificates = $Store->Certificates; if ($Certificates->Count > 0) { $Certificates = $Certificates->Find(CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, 'test1@test.ru'); } SWITCHCERT2: { if ($Certificates->Count == 0) { print "Error! Сертификат не найден!\n"; exit; } if ($Certificates->Count == 1) { $Signer2->LetProperty('Certificate',$Certificates->Item(1)); last; } print "Error! Ошибка работы с сертификатом!\n"; exit; } undef $Certificates; undef $Store; my $SignedData = Win32::OLE->new('CAPICOM.SignedData') or die "Oops, cannot start CAPICOM.SignedData"; my $Content = ''; open FileToSign, $DocName; while (<FileToSign>) { $Content .= $_; } close FileToSign; my $MyMail = MIME::Entity->build( From => 'test1@test.ru', To => 'test2@test.ru', Subject => "Test crypto".time(), Type => 'multipart/signed; protocol="application/pkcs7-signature"', Protocol => '"application/pkcs7-signature"', ); $MyMail->attach( Data => $Content, Type => "text/plain; charset=koi8-r", Encoding => "quoted-printable" ); my $ContentToSign = $MyMail->parts(0)->stringify; $ContentToSign =~ s/\n/\r\n/g; $SignedData->{'Content'} = Variant(VT_UI1, $ContentToSign); my $Message = $SignedData->Sign($Signer, 1, CAPICOM_ENCODE_BASE64); $SignedData->Verify($Message, 1, 1); $Message = $SignedData->CoSign($Signer2,CAPICOM_ENCODE_BASE64); $MyMail->attach( Data => decode_base64($Message), Type => 'application/pkcs7-signature', Name => 'smime.p7s', Disposition => 'attachment', Filename => 'smime.p7s', Description => 'S/MIME Cryptographic Signature', Encoding => "base64" ); my $smtp = Net::SMTP->new('mail.test.ru',Timeout => 30); $smtp->mail('test1@test.ru'); $smtp->recipient('test2@test.ru'); $smtp->data; $smtp->datasend($MyMail->stringify); $smtp->dataend; $smtp->close; | ||||
| ||||
а есть ли пример шифрования на perl | ||||