Статус: Участник
Группы: Участники
Зарегистрирован: 30.04.2009(UTC) Сообщений: 11
|
Добрый день! Мне нужно подписывать документы через web, и отсылать подпись на сервер и проверять ее там. Для подписи я использую CSignData.js. (пока идет только разработки приложения, поэтмоу не будем обращать внимания на то, что данный скрипт обращается напрямую к файлам). В примерах сказано, что вместе с CSignData.js нужно использовать CSignDataUse.java. Однако посмотрев строчку Код:CMSVerify.CMSVerify(cmsDer, null, encData)
(из CSignDataUse.java ) можно увидеть, что в CSignDataUse в принципе не проверяется соответствие сертификатам. Если вторым параметрам поставить не null, а конкретынй сертификат, то CMSVerify все равно не будет проверять соответствие сертификату, так как, насколько я понял, если в системе есть сертификаты, то он проверяет на соответствие им. Причем просмотрев метод verifyOnCert, который является основой проверки, можно видеть такие строки: Код:
final Asn1BerEncodeBuffer encBufSignedAttr = new Asn1BerEncodeBuffer();
info.signedAttrs.encode(encBufSignedAttr);
data = encBufSignedAttr.getMsgCopy();
и затем Код:
final Signature signature =
Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
signature.initVerify(cert);
signature.update(data);
return signature.verify(sign);
Таким образом соответствие самим данным вообще не проверяется. В файле CMS.java также есть метод CMSVerify, который, как мне кажется, делает не только проверку соответствия подписи конеретному сертификату, но и проверку соответствия данным в файле, однако если в класс CSignDataUse подставить этот метод вместо метода из класса CMSVerify, загрузив необходимый сертификат из файла, то получаем ошибку: Код: Exception in thread "main" java.lang.Exception: Invalid signature
Каким же образом правильно проверять подпись? Вот тут http://www.cryptopro.ru/...t.aspx?g=posts&t=415 был пример, однако он не работает, возможно из-за проблем с кодировкой.
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 30.04.2009(UTC) Сообщений: 11
|
Я изменил пример так, чтобы использовалась нужная кодировка UTF-16LE, получилось: Код:
public static void main(String[] args) throws Exception {
final byte[] data = Array.readFile(Constants.FILE_NAME);
final Charset charset = Charset.forName("UTF-16LE");
final CharsetEncoder encoder = charset.newEncoder();
final byte[] encData =
encoder.encode(CharBuffer.wrap(new String(data))).array();
final byte[] cmsBase = Array.readFile(Constants.CMS_FILE_NAME);
//декодирование из base64 в der
final Decoder decoder = new Decoder();
final byte[] cmsDer =
decoder.decodeBuffer(new ByteArrayInputStream(cmsBase));
final CertificateFactory cf = CertificateFactory.getInstance("X509");
final Certificate cert =
cf.generateCertificate(new FileInputStream(Constants.CERT_FILE_NAME));
final PublicKey pub = cert.getPublicKey();
//var 1
final Signature s = Signature.getInstance(JCP.CRYPTOPRO_SIGN_NAME,
JCP.PROVIDER_NAME);
s.initVerify(pub);
s.update(encData);
final boolean verifies = s.verify(cmsDer);
System.out.println("signature verifies: " + verifies);
if(!verifies) {
throw new Exception("Signature was not verified");
}
//// verify();
}
Однако данный код все равно выдает May 21, 2009 2:41:47 PM ru.CryptoPro.JCP.tools.m a INFO: Loading JCP... May 21, 2009 2:41:47 PM ru.CryptoPro.JCP.tools.m a INFO: JCP loaded. signature verifies: false Exception in thread "main" java.lang.Exception: Signature was not verified
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 23.01.2008(UTC) Сообщений: 207
Поблагодарили: 3 раз в 3 постах
|
1)примеры можно переделывать так как вам нужно (можно, например, убрать блок проверки на вложенных сертификатах и оставить блок проверки на заданных сертификатах) 2)в примере CSignDataUse уже делается перекодирование 3)подпись может быть не верна, если указать не тот сертификат 4)в версии 1.0.43 обновлены примеры CMS
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 30.04.2009(UTC) Сообщений: 11
|
Добрый день! Мне необходимо провести валидацию ЭЦП. У меня почему-то валится валидация в следующем куске: Код:
final Attribute[] signAttrElem = info.signedAttrs.elements;
//проверка аттрибута message-digest
final Asn1ObjectIdentifier messageDigestOid = new Asn1ObjectIdentifier(
(new OID(STR_CMS_OID_DIGEST_ATTR)).value);
Attribute messageDigestAttr = null;
for(int r = 0; r < signAttrElem.length; r++) {
final Asn1ObjectIdentifier oid = signAttrElem[r].type;
if(oid.equals(messageDigestOid)) {
messageDigestAttr = signAttrElem[r];
}
}
if(messageDigestAttr == null)
throw new Exception("message-digest attribute not present");
final Asn1Type open = messageDigestAttr.values.elements[0];
final Asn1OctetString hash = (Asn1OctetString)open;
final byte[] md = hash.value;
//вычисление messageDigest
final byte[] dm = digestm(text, DIGEST_ALG_NAME);
if(!Array.toHexString(dm).equals(Array.toHexString(md)))
throw new Exception("message-digest attribute verify failed");
info - это объект класса SignerInfo. Собственно валится на последнейстрочке. При этом подпись верна. Кусок, приведенный выше - это часть метода verifyOnCert из примера CMSVerify.java. Из-за чего в принципе может возникнуть такая ошибка?
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 23.01.2008(UTC) Сообщений: 207
Поблагодарили: 3 раз в 3 постах
|
каким образом было получено проверяемое сообщение?
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close