Статус: Участник
Группы: Участники
Зарегистрирован: 10.06.2021(UTC) Сообщений: 13 Откуда: Орел
|
Добрый день, возникает проблема при проверки подписи именно в java-среде, в .NET все хорошо. Ошибка появляется, если в подпись, создаваемую через браузерный плагин, добавляется атрибут со значением в виде длинной строки (больше 255 байт). Для обработки таких строк при создании подписи в браузере мы сделали следующий код: Код:
function getBstrBase64(str: string) {
let utf8 = toUTF8Array(str);
let bstrUnit8Array: Uint8Array;
// Если длина строки помещается в один байт
if (utf8.length <= 255) {
bstrUnit8Array = new Uint8Array([
0x0C,
128 + 1, // length помещается в один байт
utf8.length,
...utf8
]);
} else {
bstrUnit8Array = new Uint8Array([
0x0C,
128 + 2, // length помещается в два байта
utf8.length >> 8, // первый байт length
utf8.length & 0xFF, // второй байт length
...utf8
]);
}
return Base64.fromUint8Array(bstrUnit8Array);
}
function toUTF8Array(str: string) {
let utf8 = [];
for (let i = 0; i < str.length; i++) {
let charcode = str.charCodeAt(i);
if (charcode < 0x80) utf8.push(charcode);
else if (charcode < 0x800) {
utf8.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
} else if (charcode < 0xd800 || charcode >= 0xe000) {
utf8.push(0xe0 | (charcode >> 12),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
} else { // surrogate pair
i++;
// UTF-16 encodes 0x10000-0x10FFFF by
// subtracting 0x10000 and splitting the
// 20 bits of 0x0-0xFFFFF into two halves
charcode = 0x10000 + (((charcode & 0x3ff) << 10)
| (str.charCodeAt(i) & 0x3ff));
utf8.push(0xf0 | (charcode >> 18),
0x80 | ((charcode >> 12) & 0x3f),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
}
}
return utf8;
}
Раньше у нас был следующий код (адаптирован из https://www.cryptopro.ru...px?g=posts&t=13809), с ним проблем не возникало: Код:
function getBstrBase64(str: string) {
// Размер русских символов = символ * 2.
let RussiansSymbolsLength = 0;
let RussiansSymbols = str.match(/[А-яЁё]/g);
if (RussiansSymbols !== null)
RussiansSymbolsLength = RussiansSymbols.length;
let bstr = String.fromCharCode(0x0C) + String.fromCharCode(str.length + RussiansSymbolsLength) + str;
return Base64.encode(bstr);
}
Значение атрибута потом добавляется так: Код:
info.Attributes.push(new EncryptedAttribute(this.DocumentNameOIDAttribute, getBstrBase64(fileInfo.fileName)));
// ...
Crypto.SignData(info, dataToSign, signType, tspService);
То есть, пока мы использовали краткий формат BSTR, который допускает строки длиной меньше 255 байт все было хорошо. При переключении на длинный формат - в java-сервисе возникает ошибка Signature is invalid; error codes: [8] 'Signature is invalid'. Вот подробный лог:
θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Draining the signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Extracting certificates from signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Extracting CRLs from signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Decoding signers of signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: %%% Decoding signature... %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Collecting signers... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerFactory a FINE: New signer with type: CAdES-X Long Type 1 θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Setting certificates ands CRL for archive-timestamp if need in future... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerBESImpl b FINE: Decoding CAdES-BES signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerPKCS7Impl b FINE: Decoding PKCS7 signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 decode FINE: Decoding CAdES-X Long Type 1 structures... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 decode FINE: Decoding CAdES-T structure... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_0 decode FINE: Decoding base signer structure... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extracting signer certificate reference... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extracting certificate reference... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extract certificate reference by using current standard V2. θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_0 b FINE: Extracting existing certificate-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 b FINE: Extracting timestamps... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 b FINE: Extracting complete-certificate-references... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 e FINE: Extracting complete-revocation-references... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 f FINE: Extracting certificate-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 g FINE: Extracting revocation-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 b FINE: Extracting timestamps... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: %%% Signature has been decoded %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Extracting certificates from signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Extracting CRLs from signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 a FINE: Decoding signers of signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: %%% Decoding signature... %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Collecting signers... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerFactory a FINE: New signer with type: Enhanced signature timestamp (internal) θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Setting decoded content for timestamp... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSigner a FINE: Extracting timestamp generation date... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Setting buffered signed content θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: Setting certificates ands CRL for archive-timestamp if need in future... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerBESImpl b FINE: Decoding CAdES-BES signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerPKCS7Impl b FINE: Decoding PKCS7 signature... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 decode FINE: Decoding CAdES-X Long Type 1 structures... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 decode FINE: Decoding CAdES-T structure... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_0 decode FINE: Decoding base signer structure... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extracting signer certificate reference... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extracting certificate reference... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_3 a FINE: Extract certificate reference by using current standard V2. θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_0 b FINE: Extracting existing certificate-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 b FINE: Extracting timestamps... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 b FINE: Extracting complete-certificate-references... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 e FINE: Extracting complete-revocation-references... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 f FINE: Extracting certificate-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_7 g FINE: Extracting revocation-values... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.pc_0.pc_0.cl_5 b FINE: Extracting timestamps... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 decode FINE: %%% Signature has been decoded %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 verify FINE: %%% Verifying signature... %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.cl_1 verify FINE: Verifying signers, total: 1... θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerXLT1Impl a FINE: %%% Verifying signer... %%% θών. 10, 2021 9:40:07 AM ru.CryptoPro.CAdES.CAdESSignerXLT1Impl a FINE: Verifying binary signature... Signature is invalid; error codes: [8] 'Signature is invalid', at ru.CryptoPro.CAdES.CAdESSignerRawImpl.verifyCryptographicSignature(Unknown Source) at ru.CryptoPro.CAdES.CAdESSignerXLT1Impl.a(Unknown Source) at ru.CryptoPro.CAdES.CAdESSignerXLT1Impl.verify(Unknown Source) at ru.CryptoPro.CAdES.cl_1.verify(Unknown Source) at ru.CryptoPro.CAdES.cl_1.verify(Unknown Source) at methods.SignatureInfoMethods.getTimestamps(SignatureInfoMethods.java:108) at methods.SignatureInfoMethods.getSignatureInfo(SignatureInfoMethods.java:42) at Crypto.TestFrame$14.actionPerformed(TestFrame.java:192) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6635) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342) at java.desktop/java.awt.Component.processEvent(Component.java:6400) at java.desktop/java.awt.Container.processEvent(Container.java:2263) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Проверку вызываем следующим образом: Код:
CAdESSignature signature = getCAdESSignature();
signature.verify(null);
...
В том что значение атрибута сформировано корректно убеждаемся на сайте https://lapo.it/asn1js, если загрузить туда файл подписи, то видим значение атрибута (1.3.6.1.4.1.311.88.2.1). То есть, этот сайт успешно парсит нашу asn1 структуру, ошибок не выдает: Код:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.88.2.1 capiComDocumentName (Microsoft attribute)
SET (1 elem)
UTF8String test.docx
В .NET среде проверка у нас вызывается таким кодом, проходит успешно: Код:
var signedData = new CadesSignedData();
signedData.ContentEncoding = CADESCOM_CONTENT_ENCODING_TYPE.CADESCOM_BASE64_TO_BINARY;
var signatureString = Convert.ToBase64String(signature);
signedData.Content = Convert.ToBase64String(data.DataBytes);
signedData.VerifyCades(signatureString, DigitalSignatureKindToCadesType(signatureKind), true);
Файл, подпись и сертификат прикладываю (подпись detached) Подскажите, в чем может быть дело? fajjl, podpis', sertifikat.zip (14kb) загружен 1 раз(а).Отредактировано пользователем 10 июня 2021 г. 14:33:42(UTC)
| Причина: Не указана
|