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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline vadjunik  
#1 Оставлено : 9 сентября 2017 г. 18:36:02(UTC)
vadjunik

Статус: Активный участник

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

Сказал «Спасибо»: 15 раз
Приветствую! Столкнулся с проблемой - некорректно (как я понимаю) формируется запрос на сертификат.
Прошерстил форум, именно такой связки проблем и технологий не нашел, встреченные рекомендации пробовал - не помогает( В документации тоже ответов не нашлось (может не там искал?)

Имеем на клиентах, браузеры
GH 61.0.3163.79 (версия плагина КриптоПро 2.0.13027) (обновил в надежде на решение проблемы, не помогло, как видно)
FF 55.0.3 (версия плагина КриптоПро 2.0.12888)


Соответственно, используется асинхронный вариант API.

Сразу уточню, при запросе через API уровня ОС (работает старый NPAPI-шный плагин) - все четко.

КриптоПро CSP: 4.0.9907
Версия ядра: 4.0.9015 КС1


При запросе указываю параметры провайдера:
Тип: 80
Имя: Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider


На сервере используется штатный майкрософтовский УЦ, котором в качестве криптопровайдера указан КриптоПро (GOST R 34.10-2012).
КриптоПро CSP: 4.0.9842
Версия ядра: 4.0.9014 КС1


Код запроса отрабатывает корретно.

Код:
<script type="text/javascript">

var ENROLL_X500NAME_FLAGS = {
    XCN_CERT_NAME_STR_NONE                       : 0,
    XCN_CERT_SIMPLE_NAME_STR                     : 0x00000001, // Это флаг плагину не нравится, ругается: The parameter is incorrect. (0x80070057)
    XCN_CERT_OID_NAME_STR                        : 0x00000002,
    XCN_CERT_X500_NAME_STR                       : 0x00000003,
    XCN_CERT_XML_NAME_STR                        : 0x00000004,
    XCN_CERT_NAME_STR_SEMICOLON_FLAG             : 0x40000000,
    XCN_CERT_NAME_STR_NO_PLUS_FLAG               : 0x20000000,
    XCN_CERT_NAME_STR_NO_QUOTING_FLAG            : 0x10000000,
    XCN_CERT_NAME_STR_CRLF_FLAG                  : 0x8000000,
    XCN_CERT_NAME_STR_COMMA_FLAG                 : 0x4000000,
    XCN_CERT_NAME_STR_REVERSE_FLAG               : 0x2000000,
    XCN_CERT_NAME_STR_FORWARD_FLAG               : 0x1000000,
    XCN_CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG      : 0x10000,
    XCN_CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG    : 0x20000,
    XCN_CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG   : 0x40000,
    XCN_CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG    : 0x80000,
    XCN_CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG  : 0x100000
};

function(fullName, providerType, providerName) 
{        
      // Ф-я ExecWithPlugin просто обертка над cadesplugin.async_spawn, перехватывающая и расшифровывающая ошибки.
      ExecWithPlugin(function* () { 

            // Ф-я GetEnrollObject - обертка для создания асинхронного объекта из пространства имен X509Enrollment
            var privateKey = yield* GetEnrollObject("CX509PrivateKey");             
            yield privateKey.propset_ProviderName(providerName);
            yield privateKey.propset_ProviderType(providerType);
            yield privateKey.propset_KeySpec(ENROLL_X509KEYSPEC.XCN_AT_SIGNATURE);                

            var certificateRequestPkcs10 = yield* GetEnrollObject("CX509CertificateRequestPkcs10");
            yield certificateRequestPkcs10.InitializeFromPrivateKey(ENROLL_CONTEXT.ContextUser, privateKey, ""); 

            var distinguishedName = yield* GetEnrollObject("CX500DistinguishedName");
                        
            // fullName - проиндексированный OID(ами) массив значений для RDN.

            var certName = "";
            var oids = Object.keys(fullName);
            
            for(var i = 0; i < oids.length; i++){
                if (certName != "")
                    certName += ", ";
                
                certName += (oids[i] + "=" + fullName[oids[i]]);  
            }
                                                        
            yield distinguishedName.Encode(certName, ENROLL_X500NAME_FLAGS.XCN_CERT_NAME_STR_NONE); 
            yield certificateRequestPkcs10.propset_Subject(distinguishedName);

            var keyUsageExtension = yield* GetEnrollObject("CX509ExtensionKeyUsage");
                        
            yield keyUsageExtension.InitializeEncode(
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_NON_REPUDIATION_KEY_USAGE);
                        
            yield (yield certificateRequestPkcs10.X509Extensions).Add(keyUsageExtension);

            var enroll = yield* GetEnrollObject("CX509Enrollment");
            yield enroll.InitializeFromRequest(certificateRequestPkcs10);
                
            // Пробовал менять тип кодировки при значении XCN_CRYPT_STRING_BINARY  получаю: 
            // Данные ASN1 повреждены. 0x80093103 (ASN: 259)

            // А при XCN_CRYPT_STRING_NOCR - Падает сам плагин (в Хроме).             
                                      // Сигнатура проблемы:
                                      // Имя события проблемы:	APPCRASH
                                      // Имя приложения:	nmcades.exe
                                      // Версия приложения:	1.0.10478.0
                                      // Отметка времени приложения:	597d48c9
                                      // Имя модуля с ошибкой:	nmcades.exe
                                      // Версия модуля с ошибкой:	1.0.10478.0
                                      // Отметка времени модуля с ошибкой:	597d48c9
                                      // Код исключения:	40000015
                                      // Смещение исключения:	000166f5
                                      // Версия ОС:	6.1.7601.2.1.0.256.48
                                      // Код языка:	1049
                                      // Дополнительные сведения 1:	177b
                                      // Дополнительные сведения 2:	177b64d1b0e35f4876ae099d0b42016e
                                      // Дополнительные сведения 3:	7793
                                      // Дополнительные сведения 4:	7793eef4e9c0c3a122a47f8bca2bf0a0
                                            
            var certReq = yield enroll.CreateRequest(ENROLL_ENCODING_TYPE.XCN_CRYPT_STRING_BASE64); 
            var containerName = yield privateKey.ContainerName;
    });
}
</script>


Значения флагов и констант взяты из MSDN, только флаги в ENROLL_X500NAME_FLAGS привел к единообразному 16-ричному виду, может как-то не так (добавил в исходник сюда)?

Но в итоге на сервере, при отправке запроса ЦС, получаю сообщение:
Встречено неверное значение тега ASN1. 0x8009310b (ASN: 267)

Кроме экспериментов с кодировкой самого запроса, пробовал по всякому формировать RDN (штано OID=значение) через ", ". Никаких изменений ( Руками делал строку, в которой забирал значения параметров с пробелами в кавычки, результат прежний.

Вот тут сам файл запроса, уже приехавший на сервер.

Может глаза замылились не вижу очевидной ошибки?
Offline vadjunik  
#2 Оставлено : 10 сентября 2017 г. 20:05:02(UTC)
vadjunik

Статус: Активный участник

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

Сказал «Спасибо»: 15 раз
Добавил подключение расширения с описаниями алгоритмов (для ГОСТ 2012 их несколько поменялось):

Код:

ODI: 1.2.643.7.1.1.2.2 object: ГОСТ Р 34.11-2012 256 бит
ODI: 1.2.643.2.2.21    object: ГОСТ 28147-89
ODI: 1.2.643.7.1.1.3.2 object: ГОСТ Р 34.11-2012/34.10-2012 256 бит
ODI: 1.2.643.7.1.1.6.1 object: ГОСТ Р 34.10-2012 DH 256 бит


Код:

<script type="text/javascript">
            var privateKey = yield* GetEnrollObject("CX509PrivateKey");
            
            yield privateKey.propset_ProviderName(providerName);
            yield privateKey.propset_ProviderType(providerType);
            yield privateKey.propset_KeySpec(ENROLL_X509KEYSPEC.XCN_AT_SIGNATURE);                

            var certRequest = yield* GetEnrollObject("CX509CertificateRequestPkcs10");
            yield certRequest.InitializeFromPrivateKey(ENROLL_CONTEXT.ContextUser, privateKey, "");

            var distinguishedName = yield* GetEnrollObject("CX500DistinguishedName");
                        
            var certName = "";
            var oids = Object.keys(requestData.DN);
            
            for(var i = 0; i < oids.length; i++){
                if (certName != "")
                    certName += ", ";
                
                certName += (oids[i] + "=" + requestData.DN[oids[i]]);  
            }
                                                         
            yield distinguishedName.Encode(certName, ENROLL_X500NAME_FLAGS.XCN_CERT_NAME_STR_NONE); 
            yield certRequest.propset_Subject(distinguishedName);

            // Указывем алгорит хеширования.
            var hashAlgo = yield* GetEnrollObject("CObjectId"); 
            yield hashAlgo.InitializeFromValue(requestData.hashAlgorithm);            
            yield certRequest.propset_HashAlgorithm(hashAlgo);

            var keyUsageExtension = yield* GetEnrollObject("CX509ExtensionKeyUsage");
                        
            yield keyUsageExtension.InitializeEncode(
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                        ENROLL_X509KEYUSAGE_FLAGS.XCN_CERT_NON_REPUDIATION_KEY_USAGE);
              
            var requestExtensions = yield certRequest.X509Extensions;
             
            yield requestExtensions.Add(keyUsageExtension);
             
            // ========================================================
            // Добавление используемых алгоритмов.
            var algoCollection = yield* GetEnrollObject("CObjectIds");
			
			for(var i = 0; i < requestData.algoDescriptors.length; i++ )
			{
                var algo = yield yield* GetEnrollObject("CObjectId");
				yield algo.InitializeFromValue(requestData.algoDescriptors[i]);
				yield algoCollection.Add(algo);
			}
            
            // Расширение описаний используемых алгоритмов.
            var algoExtension = yield* GetEnrollObject("CX509ExtensionEnhancedKeyUsage");            
            yield algoExtension.InitializeEncode(algoCollection);           
            yield requestExtensions.Add(algoExtension);
            // ========================================================

            // Формирование запроса на сертификат.
            var enroll = yield* GetEnrollObject("CX509Enrollment");
            yield enroll.InitializeFromRequest(certRequest);
            var certReq = yield enroll.CreateRequest(ENROLL_ENCODING_TYPE.XCN_CRYPT_STRING_BASE64); 
            var containerName = yield privateKey.ContainerName;
                          
            return success({cert:certReq, containerName:containerName});
</script>


Увы, ситуация без изменения? Куда копать дальше?

Отредактировано пользователем 11 сентября 2017 г. 0:03:45(UTC)  | Причина: Не указана

Offline vadjunik  
#3 Оставлено : 11 сентября 2017 г. 18:47:02(UTC)
vadjunik

Статус: Активный участник

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

Сказал «Спасибо»: 15 раз
Дело в двойной кодировке полученного от плагина запроса в base64!!! ) Спасибо сотрудникам КриптоПро за помощь!
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.