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

Уведомление

Icon
Error

5 Страницы123>»
Опции
К последнему сообщению К первому непрочитанному
Offline akor81  
#1 Оставлено : 20 сентября 2012 г. 0:29:48(UTC)
akor81

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

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

Подскажите, пожалуйста, как мне создать обычную подпись с помощью плагина для браузеров? В его описании написано:
"КриптоПро ЭЦП Browser plug-in позволяет создавать и проверять как обычную электронную подпись, так и усовершенствованную электронную подпись". Но я не нашёл примеров создания обычной подписи, только усовершенствованной.
Offline Андрей Писарев  
#2 Оставлено : 20 сентября 2012 г. 0:56:52(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,340
Мужчина
Российская Федерация

Сказал «Спасибо»: 550 раз
Поблагодарили: 2212 раз в 1727 постах
akor81 написал:
Подскажите, пожалуйста, как мне создать обычную подпись с помощью плагина для браузеров? В его описании написано:
"КриптоПро ЭЦП Browser plug-in позволяет создавать и проверять как обычную электронную подпись, так и усовершенствованную электронную подпись". Но я не нашёл примеров создания обычной подписи, только усовершенствованной.


есть как минимум на demo-странице

http://www.cryptopro.ru/cadesplugin/Default.aspx
выбор:
Тип подписи
=> Простая подпись

в коде:
http://www.cryptopro.ru/cadesplugin/Code.js

Отредактировано пользователем 20 сентября 2012 г. 0:58:31(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Новожилова Елена  
#3 Оставлено : 20 сентября 2012 г. 16:41:55(UTC)
Новожилова Елена

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

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 924
Женщина
Откуда: Крипто-Про

Поблагодарили: 99 раз в 95 постах
Смотрите примеры на создание подписи CAdES-BES. Это и есть обычная подпись.
Offline akor81  
#4 Оставлено : 20 сентября 2012 г. 17:33:54(UTC)
akor81

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

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

Спасибо за ответы! Этот вопрос я для себя уяснил.

А не могли бы вы подсказать, как эту подпись теперь можно верифицировать на серверной стороне средствами JCP? Проблема в следующем. Подпись я получил, вывел на экран в виде строки, выделил мышкой и скопировал в буфер. Затем я захардкодил её в свой джава-код в виде стринговой константы и пытаюсь написать некий код, который бы её верифицировал (пока просто в целях эксперимента, чтобы научиться со всем этим работать). Я пытаюсь это делать как-то вот так:

public boolean verifySignedMessage(Certificate certificate, String message, String signature) {
Signature sig = Signature.getInstance("GOST3411withGOST3410EL"); //Может быть, тут нужно указать другой алгоритм? Но какой? Я пробовал с разными.
sig.initVerify(certificate);
sig.update(message.getBytes());
byte[] sigBytes = signature.getBytes();
return sig.verify(sigBytes);
}


И эта штука мне всегда возвращает false :( Я что-то не так делаю? Может, нужно перекодировать байты подписи или исходного сообщения в другую кодировку? Но если да, то в какую?



Вот мой код получения подписи на стороне джаваскрипта:

var CADESCOM_CADES_BES = 1;
var CAPICOM_CURRENT_USER_STORE = 2;
var CAPICOM_MY_STORE = "My";
var CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
var CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;
var certSubjectName = "signer_name";
var dataToBeSigned = "Message";
...
var oStore = CreateObject("CAPICOM.Store");
oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
var oCertificates = oStore.Certificates.Find(
CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, certSubjectName);
var oCertificate = oCertificates.Item(1);
var oSigner = CreateObject("CAdESCOM.CPSigner");
oSigner.Certificate = oCertificate;
oSigner.TSAAddress = "http://cryptopro.ru/tsp/";
var oSignedData = CreateObject("CAdESCOM.CadesSignedData");
oSignedData.Content = dataToBeSigned;
oSigner.Options = 1;
var sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_BES);
alert(sSignedMessage);
...


Помогите разобраться, пожалуйста!
Offline Евгений Афанасьев  
#5 Оставлено : 20 сентября 2012 г. 18:25:21(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,963
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 704 раз в 665 постах
Здравствуйте.
Так (ваш пример проверки на java) вы можете проверить обычную подпись размером 64-байта. CAdES-BES имеет иную структуру (CMS подпись), поэтому рекомендую посмотреть примеры в samples.jar/CMS_samples (дистрибутив JCP) для проверки подписи.
Или попробовать http://cryptopro.ru/news...si-formata-cades-na-java

Отредактировано пользователем 20 сентября 2012 г. 18:27:15(UTC)  | Причина: Не указана

Offline akor81  
#6 Оставлено : 25 сентября 2012 г. 18:51:52(UTC)
akor81

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

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

Спасибо. Я попробовал на практике эти примеры. Подпись они верифицируют, но только подпись саму по себе, БЕЗ привязки к подписываемым данным. Т.е. проверяется, что переданный на верификацию массив байтов - это валидная электронная подпись. Но это не то, что мне требуется :( Мне требуется убедиться, что эта подпись соответствует именно тем данным, которые я подписывал.

Я ещё раз поясню, что мне нужно научиться делать.

Вот у меня есть какие-то данные, предположим, вот такой текст: "Message". Я хочу для этих данных сгенерировать электронную подпись. Я её средствами плагина сгенерировал, пока всё ок. Дальше я хочу на сервере проверить, соответствует ли эта моя полученная подпись данным которые я подписывал (в данном случае, строке "Message"). И вот тут-то у меня затык и происходит...

Верификация средствами JCP производится как-то так:

// проверка подписи
final Signature signature =
Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
signature.initVerify(cert);
signature.update(data); //в данном случае это "Message".getBytes()
return signature.verify(signedData); //signedData - это тот массив байтов, который я сгенерировал плагином, возможно, с какими-то преобразованиями


Уважаемый afev мне объяснил, что плагином я получил некую CMS подпись. Ок, я посмотрел примеры и преобразовал её к 64-байтному виду. Я делал это вот так:

public static byte[] transformCmsToUsual(byte[] signedData) throws Exception {
signedData = Base64.decode(signedData);
Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(signedData);
ContentInfo contentInfo = new ContentInfo();
contentInfo.decode(asnBuf);
SignedData cms = (SignedData) contentInfo.content;
SignerInfo info = cms.signerInfos.elements[0];
return info.signature.value;
}

И сам по себе верифицирующий метод выглядит так:

public static boolean verifySignature() throws Exception {
Signature signature = Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
signature.initVerify(getCertificate());
signature.update("Message".getBytes());
byte[] signedData = transformCmsToUsual(SIGNED_DATA_FROM_PLUGIN.getBytes());
return signature.verify(signedData);
}


И всё равно я получаю false. Что не так, подскажите пожалуйста!?
Offline Андрей Писарев  
#7 Оставлено : 25 сентября 2012 г. 19:12:43(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,340
Мужчина
Российская Федерация

Сказал «Спасибо»: 550 раз
Поблагодарили: 2212 раз в 1727 постах
Цитата:
Подпись они верифицируют, но только подпись саму по себе, БЕЗ привязки к подписываемым данным. Т.е. проверяется, что переданный на верификацию массив байтов - это валидная электронная подпись.


d'oh! /

как без привязки... ? Зачем тогда ЭЦП, если я могу менять данные, а ЭЦП остается валидной!

Цитата:

Т.е. проверяется, что переданный на верификацию массив байтов - это валидная электронная подпись

Как? Опиши алгоритм, очень интересно! Очень убедительные слова...

Отредактировано пользователем 25 сентября 2012 г. 19:18:25(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Афанасьев  
#8 Оставлено : 25 сентября 2012 г. 19:26:20(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,963
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 704 раз в 665 постах
akor81 написал:

public static boolean verifySignature() throws Exception {
Signature signature = Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
signature.initVerify(getCertificate());
signature.update("Message".getBytes());
byte[] signedData = transformCmsToUsual(SIGNED_DATA_FROM_PLUGIN.getBytes());
return signature.verify(signedData);
}


И всё равно я получаю false. Что не так, подскажите пожалуйста!?


Посмотрите пример CMSVerify, в частности, проверку подписи CMSVerify.CMSVerify() - проверять следует не по подписанным данным (тексту, файлу и т.п.), а по подписываемым аттрибутам (signed attributes) в CAdES-BES подписи.

Отредактировано пользователем 25 сентября 2012 г. 19:27:56(UTC)  | Причина: Не указана

Offline akor81  
#9 Оставлено : 25 сентября 2012 г. 19:40:52(UTC)
akor81

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

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

Андрей * написал:
как без привязки... ? Зачем тогда ЭЦП, если я могу менять данные, а ЭЦП остается валидной!


Потому что ЭЦП сама в себе содержит какие-то атрибуты, которым она должна соответствовать. И в примере они оттуда вынимаются, а потом проверяется, что ЭЦП им соответствует. Мне это тоже кажется бессмысленным... Конечно, я мог что-то не так понять, это весьма вероятно. И если я это неправильно понял, а ты мне объяснишь как правильно - это будет даже очень хорошо! :)

Андрей * написал:
Как? Опиши алгоритм, очень интересно! Очень убедительные слова...


Описать алгоритм я затрудняюсь. Но вот код примера, который мне посоветовали посмотреть:

Пример из samples_src.jar\CMS_samples написал:

public static void main(String[] args) throws Exception {
//данные для проверки (CMS)
final byte[] signdata = Array.readFile(CMS_FILE_PATH);
// final Certificate cert = CMStools.loadCertificate(CMStools.SIGN_KEY_NAME);
//Certificate cert = CMStools.readCertificate(CMStools.SIGN_CERT_PATH);

//проверка
final Certificate[] certs = new Certificate[1];
certs[0] = CMStools.loadCertificate(CMStools.SIGN_KEY_NAME);
CMSVerify(signdata, certs, null);
}

/**
* проверка CMS
*
* @param buffer буфер
* @param certs сертификаты
* @param data данные
* @throws Exception e
*/
public static void CMSVerify(byte[] buffer, Certificate[] certs, byte[] data)
throws Exception {
//clear buffers fo logs
out = new StringBuffer("");
out1 = new StringBuffer("");
final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
final ContentInfo all = new ContentInfo();
all.decode(asnBuf);
if (!new OID(CMStools.STR_CMS_OID_SIGNED).eq(all.contentType.value))
throw new Exception("Not supported");
final SignedData cms = (SignedData) all.content;
final byte[] text;
if (cms.encapContentInfo.eContent != null)
text = cms.encapContentInfo.eContent.value;
else if (data != null) text = data;
else throw new Exception("No content for verify");
OID digestOid = null;
final DigestAlgorithmIdentifier digestAlgorithmIdentifier =
new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID).value);
for (int i = 0; i < cms.digestAlgorithms.elements.length; i++) {
if (cms.digestAlgorithms.elements[i].algorithm
.equals(digestAlgorithmIdentifier.algorithm)) {
digestOid =
new OID(cms.digestAlgorithms.elements[i].algorithm.value);
break;
}
}
if (digestOid == null)
throw new Exception("Unknown digest");
final OID eContTypeOID = new OID(cms.encapContentInfo.eContentType.value);
if (cms.certificates != null) {
//Проверка на вложенных сертификатах
CMStools.logger.info("Validation on certificates founded in CMS.");
for (int i = 0; i < cms.certificates.elements.length; i++) {
final Asn1BerEncodeBuffer encBuf = new Asn1BerEncodeBuffer();
cms.certificates.elements[i].encode(encBuf);

final CertificateFactory cf =
CertificateFactory.getInstance("X.509");
final X509Certificate cert =
(X509Certificate) cf
.generateCertificate(encBuf.getInputStream());

for (int j = 0; j < cms.signerInfos.elements.length; j++) {
final SignerInfo info = cms.signerInfos.elements[j];
if (!digestOid
.equals(new OID(info.digestAlgorithm.algorithm.value)))
throw new Exception("Not signed on certificate.");
final boolean checkResult = verifyOnCert(cert,
cms.signerInfos.elements[j], text, eContTypeOID);
writeLog(checkResult, j, i, cert);
}
}
} else if (certs != null) {
//Проверка на указанных сертификатах
CMStools.logger.info("Certificates for validation not found in CMS.\n" +
" Try verify on specified certificates...");
for (int i = 0; i < certs.length; i++) {
final X509Certificate cert = (X509Certificate) certs[i];
for (int j = 0; j < cms.signerInfos.elements.length; j++) {
final SignerInfo info = cms.signerInfos.elements[j];
if (!digestOid.equals(new OID(
info.digestAlgorithm.algorithm.value)))
throw new Exception("Not signed on certificate.");
final boolean checkResult = verifyOnCert(cert,
cms.signerInfos.elements[j], text, eContTypeOID);
writeLog(checkResult, j, i, cert);
}
}
} else {
CMStools.logger.warning("Certificates for validation not found");
}
if (validsign == 0) throw new Exception("Signatures are invalid" + out1);
if (cms.signerInfos.elements.length > validsign)
throw new Exception("Some signatures are invalid:" + out + out1);
else CMStools.logger.info("All signatures are valid:" + out);
}



Как видим, в этом примере метод CMSVerify(signdata, certs, null) вызывается с null вместо реальных данных, соответствующих подписи. И тем не менее, чего-то там внутри верифицируется, правильно? Внутри этого метода мы видим:

final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
final ContentInfo all = new ContentInfo();
all.decode(asnBuf);
final SignedData cms = (SignedData) all.content;
final byte[] text;
if (cms.encapContentInfo.eContent != null)
text = cms.encapContentInfo.eContent.value;

И дальше все верификация крутится вокруг этого массива text, который получен из самой подписи.
Вот я попробовал этот метод запустить для моей сгенерированной плагином подписи, которая соответствует строке "Message". Так вот в этой получившейся подписи cms.encapContentInfo.eContent.value != "Message".getBytes() :( И я не знаю, как мне установить соответствие между получившейся подписью и строкой "Message"

Отредактировано пользователем 26 сентября 2012 г. 0:15:24(UTC)  | Причина: Не указана

Offline Андрей Писарев  
#10 Оставлено : 25 сентября 2012 г. 19:48:37(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,340
Мужчина
Российская Федерация

Сказал «Спасибо»: 550 раз
Поблагодарили: 2212 раз в 1727 постах
akor81 написал:
Андрей * написал:
как без привязки... ? Зачем тогда ЭЦП, если я могу менять данные, а ЭЦП остается валидной!


Потому что ЭЦП сама в себе содержит хэш данных, которому она соответствует. И в примере они оттуда вынимаются, а потом проверяется, что ЭЦП этому хэшу данных соответствует. Мне это тоже кажется бессмысленным... Конечно, я мог что-то не так понять, это весьма вероятно. И если это так - это даже очень хорошо! :)

Андрей * написал:
Как? Опиши алгоритм, очень интересно! Очень убедительные слова...


Описать алгоритм я затрудняюсь. Но вот код примера, который мне посоветовали посмотреть:



Значение ЭЦП = это зашифрованный с помощью ЗАКРЫТОГО ключа хеш (в результате хеширования данных). размер = 256 бит.
Для проверки нужен открытый ключ автора (например, из сертификата), с помощью которого происходит расшифровка хеша.
Если она удается (! = значит это автор)- далее проверяется соответствие расшифрованного хеша и вновь рассчитанного сейчас хеша от данных.
если хеши совпадают = подпись верна и автор - владелец открытого ключа ( сертификата )

Отредактировано пользователем 25 сентября 2012 г. 19:49:13(UTC)  | Причина: Не указана

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