Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline poltora  
#1 Оставлено : 28 апреля 2008 г. 20:03:52(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

ниже представлен тестовый пример, который подписывает тестовые данные и тут же проверяет подпись.

проблема в том, что подпись является невалидной.

Код:

# идентификатор юзера, по которому находится сертияикат (ниже)
my $user = '18b729e9d7485c1b12964e2ef3fba8a8'; 
my $data = '1234567890';


# ищем сертификат
my $Store = Win32::OLE->new('CAPICOM.Store') or die "Cannot start CAPICOM.Store";
$Store->Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY );

my $Certificates = $Store->Certificates;
my $certificate;
for ( my $i = 1 ; $i <= $Certificates->Count() ; $i++ ) {
	my $Certificate = $Certificates->Item($i);
	if ( hashSubjectName( $Certificate->SubjectName() ) eq $user ) {
		$certificate = $Certificate;
		last;
	}
}
# да, наш сертификат, имеет приватный ключ $Certificate->HasPrivateKey()
print $certificate->SubjectName(); 

# подписываем выше найденным сертификатом
my $Signer = Win32::OLE->new('CAPICOM.Signer') or die "Cannot start CAPICOM.Signer";
$Signer->LetProperty( 'Certificate', $certificate );

my $SignedData = Win32::OLE->new('CAPICOM.SignedData') or die "Cannot start CAPICOM.SignedData";
$SignedData->LetProperty( 'Content', $data ); # или $SignedData->Content($data) ?
my $signature = $SignedData->Sign( $Signer, 1, CAPICOM_ENCODE_BASE64 );

# что-то есть
print $signature; 

# проверяем подпись
my $SignedData = Win32::OLE->new('CAPICOM.SignedData') or die "Cannot start CAPICOM.SignedData";
$SignedData->LetProperty( 'Content', $data ); #или $SignedData->Content($data) ?

# возвращается undef, что значает, что подпись неверна (и так ли это?)
print $SignedData->Verify( $signature, 1, CAPICOM_VERIFY_SIGNATURE_ONLY );




если вывести все переменные сертификата из подписи(!) -
$SignedData->Certificates(1);
- то окажется, что он похож на исходный сертификатор (которым подписывали), НО он не имеет приватного ключа ($Certificate->HasPrivateKey())

в каком месте я допускаю ошибку?

имеет смысл использовать CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE ?
заранее спасибо.



Отредактировано пользователем 29 апреля 2008 г. 22:23:08(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#2 Оставлено : 28 апреля 2008 г. 20:47:03(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Попробуйте тоже самое с присоединенной подписью
Техническую поддержку оказываем тут
Наша база знаний
Offline poltora  
#3 Оставлено : 28 апреля 2008 г. 21:47:21(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

Kirill Sobolev написал:
Попробуйте тоже самое с присоединенной подписью


правильно я понимаю, что вы предлагаете подписать документ сторонней утилитой и затем отправить на сервер?

Offline poltora  
#4 Оставлено : 28 апреля 2008 г. 22:08:17(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

любопытно, что аналогичный скрипт на javascript (клиент и сервер, в данном случае - одна физическая машина) - прекрасно работает. и к томуже намного(!) быстрее - доли секунды.
на perl занимает несколько десятков секунд.

вот пример javascript:

Код:

&lt;object id="oCAPICOM"
    codeBase="http://download.microsoft.com/download/E/1/8/E18ED994-8005-4377-A7D7-0A8E13025B94/capicom.cab#version=2,0,0,3"
    classid="clsid:A996E48C-D3DC-4244-89F7-AFA33EC60679"
    VIEWASTEXT>
&lt;/object>

&lt;script>
var CAPICOM_STORE_OPEN_READ_ONLY = 0;
var CAPICOM_CURRENT_USER_STORE = 2;
var CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;

var CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME = 0;
var CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME = 1;
var CAPICOM_VERIFY_SIGNATURE_ONLY = 0;

var Now = new Date();

var CertStore = new ActiveXObject("CAPICOM.Store");
var Signer = new ActiveXObject("CAPICOM.Signer");
var SignedAuth = new ActiveXObject("CAPICOM.SignedData");

CertStore.Open(CAPICOM_CURRENT_USER_STORE, "MY", CAPICOM_STORE_OPEN_READ_ONLY);
Signer.Certificate = CertStore.Certificates.Item(1); // 1-ый из личного хранилища сертификатов, поскольку мы работаем на стороне клиента

SignedAuth.Content = "бла бла бла"; // текст документа, который будем подписывать

document.write("text:\r\n" + SignedAuth.Content + "\r\n\r\n");
document.write("signing... ");

try {
    var Signature = SignedAuth.Sign(Signer, true); // подписываем, получаем подпись Signature на основе документа и сертификата
} catch (e) {
    document.write("failed: " + e.message + "\r\n\r\n"); // ошибка
}

document.write("done\r\n\r\n");
document.write("signature:\r\n" + Signature + "\r\n");

document.write("-------------------------------------------------------------------\r\n\r\n");

// Проверка подписи...
var SData = new ActiveXObject("CAPICOM.SignedData");
SData.Content = "бла бла бла"; // текст проверяемого документа

document.write("text:\r\n" + SData.Content + "\r\n\r\n");
document.write("signature:\r\n" + Signature + "\r\n");
document.write("verifying... ");

try {
    SData.Verify(Signature, true, CAPICOM_VERIFY_SIGNATURE_ONLY);
    document.write("done\r\n\r\n");
    var Certificate=SData.Certificates(1);
    var CertOwner=Certificate.GetInfo(CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME);
    document.write("signer: " + CertOwner);
} catch (e) {
    document.write("failed: " + e.message + "\r\n\r\n"); // либо подпись либо документ липовые
}

&lt;/script>





Отредактировано пользователем 29 апреля 2008 г. 22:25:09(UTC)  | Причина: Не указана

Offline poltora  
#5 Оставлено : 29 апреля 2008 г. 0:30:02(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

добавлю, что пример определения валидности сертификата, который дается на
http://www.cryptopro.ru/...ro/forum/view.asp?q=1105

Certificate.IsValid().CheckFlag
Certificate.IsValid().Result
Chain.Build(Certificate)

возвращают статус CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN

означает ли это, что сертификат неверно сгенерирован или еще что нить в этом роде?
как в таком случае, генерация подписи и ее последующая проверка с помошью javascript (выше) нормально отрабатывает?
Offline Kirill Sobolev  
#6 Оставлено : 29 апреля 2008 г. 14:21:40(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
poltora написал:

правильно я понимаю, что вы предлагаете подписать документ сторонней утилитой и затем отправить на сервер?

нет, я предлагаю в качестве 2го параметра в вызове SignedData.Sign передать false.
poltora написал:
возвращают статус CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN
означает ли это, что сертификат неверно сгенерирован или еще что нить в этом роде?
как в таком случае, генерация подписи и ее последующая проверка с помошью javascript (выше) нормально отрабатывает?

нет, это означает что сертификат не удалось проверить на отзыв.
Техническую поддержку оказываем тут
Наша база знаний
Offline poltora  
#7 Оставлено : 29 апреля 2008 г. 19:58:40(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

связана ли эта ошибка с невалидностью подписи?
как указать не проверять сертификат на отзыв и поможет ли это решению проблемы(проверка валидности подписи)?
Offline Kirill Sobolev  
#8 Оставлено : 29 апреля 2008 г. 21:23:08(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
а в Вашем коде сертификат на отзыв и не проверяется - вы же передаете CAPICOM_VERIFY_SIGNATURE_ONLY
Техническую поддержку оказываем тут
Наша база знаний
Offline poltora  
#9 Оставлено : 29 апреля 2008 г. 22:19:08(UTC)
poltora

Статус: Участник

Группы: Участники
Зарегистрирован: 28.04.2008(UTC)
Сообщений: 11

Kirill Sobolev написал:
а в Вашем коде сертификат на отзыв и не проверяется - вы же передаете CAPICOM_VERIFY_SIGNATURE_ONLY


получается, что я указываю не проверять на отзыв сертификат и получаю ошибку - "сертификат не удалось проверить на отзыв" ???

а как просто проверить на валидность сертификат?
вот пример кода - достаем сертификат из хранилища, и тут же проверяем его по рецепту http://www.cryptopro.ru/...ro/forum/view.asp?q=1105
в результате - срабатывание на CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN


Код:

# идентификатор юзера, по которому находим сертификат
	my $user = '18b729e9d7485c1b12964e2ef3fba8a8';

	my $Store = Win32::OLE->new('CAPICOM.Store') or die "Cannot start CAPICOM.Store";
	$Store->Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY );
	my $Certificates = $Store->Certificates;

	my $Certificate;
	for ( my $i = 1 ; $i <= $Certificates->Count() ; $i++ ) {
		my $Cert = $Certificates->Item($i);
		if ( _CertificateSubjectName2SSL_CLIENT_S_DN( $Cert->SubjectName() ) eq $user ) {
			$Certificate = $Cert;
			last;
		}
	}
# нашли, выводим имя и наличие приватного ключа - угу, он самый
	print $Certificate->SubjectName() . ' ' . $Certificate->HasPrivateKey();

# проверяем на валидность
	my $CertificateStatus = $Certificate->IsValid();
	$CertificateStatus->CheckFlag(
								        CAPICOM_CHECK_TRUSTED_ROOT
									 or CAPICOM_CHECK_TIME_VALIDITY
									 or CAPICOM_CHECK_SIGNATURE_VALIDITY
									 or CAPICOM_CHECK_ONLINE_REVOCATION_STATUS
	);

	if ( $CertificateStatus->Result() ) {
		print "CryptoAPI believes to be trustworthy.";
	}
	else {
		my $Chain = Win32::OLE->new("CAPICOM.Chain") or die "Cannot start CAPICOM.Store";
		$Chain->Build($Certificate);

#...пропущено...

# срабатывает на этот код
		if ( CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN & $Chain->Status() ) {
			print 
			    "CryptoAPI was unable to determine the certificate status for &rsquo;"
			  . $Certificate->GetInfo(CAPICOM_INFO_SUBJECT_SIMPLE_NAME)
			  . "&rsquo;";
		}
	}



или у меня неверный сертификат. или я проверяю неверно.
подскажите, где ошибка.
видимо из-за этой проблемы при проверке (в первом примере) на валидность подписи я получаю ошибку, хотя эта подпись сгенерирована тут же...


Отредактировано пользователем 29 апреля 2008 г. 22:19:43(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#10 Оставлено : 30 апреля 2008 г. 15:12:00(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
"poltora" написал:
получается, что я указываю не проверять на отзыв сертификат и получаю ошибку - "сертификат не удалось проверить на отзыв" ???

а с чего Вы взяли что в 1м примере у вас ошибка проверки на отзыв?
"poltora" написал:
а как просто проверить на валидность сертификат?

ну Вы же сами указываете правильный способ
"poltora" написал:
пример определения валидности сертификата, который дается на
http://www.cryptopro.ru/...ro/forum/view.asp?q=1105

Certificate.IsValid().CheckFlag
Certificate.IsValid().Result
Chain.Build(Certificate)

"poltora" написал:
или у меня неверный сертификат. или я проверяю неверно.

я думаю у вас просто нет локально установленного CRL
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.