|
Доступ к хранилищу сертификатов ЭП из сеанса под IIS | ☑ | ||
---|---|---|---|---|
0
Gleb K
26.07.16
✎
10:30
|
win2008r2 + 1С 8.3 + IIS
Имею http-сервис опубликованный на IIS, необходимо работать с ЭП (проверять подпись запроса и формировать подпись для ответа). Пул приложений 1С в ISS стартует под собственным пользователем IIS APPPOOL 1C. Свой сертификат RSA с закрытым ключом установил в хранилище компьютера\личные, дал полные права доступа к нему пользователю IIS APPPOOL 1C (пробовал как через mmc, так и через утилиту winhttpcertcfg). Также пробовал ставить сертификат в хранилище пользователя\личные. Следующий код не видит сертификата: МК = Новый МенеджерКриптографии("Microsoft Enhanced Cryptographic Provider v1.0","",1); //здесь пробовал хранилище и компьютера и пользователя ХранилищеСертификатов = МК.ПолучитьХранилищеСертификатов(); //Не видит как в лоб Сертификат = ХранилищеСертификатов.НайтиПоОтпечатку(Base64Значение("a624b6ae158e677113d2fce3e66e332a342e0a87")); //так и в общем Сертификат = ХранилищеСертификатов2.ПолучитьВсе(); Также пробовал стартовать пул приложений 1С под учеткой Network service и под своей личной учеткой - не помагает. Если запустить толстый клиент на этой машине, то сертификат видится без проблем. Ребята, есть идеи? |
|||
1
Gleb K
26.07.16
✎
16:48
|
Ап.
|
|||
2
igork1966
26.07.16
✎
17:15
|
Полагаю что ветка реестра "хранилище компьютера\личные"
не видна под другим пользователем, не? |
|||
3
Gleb K
26.07.16
✎
23:43
|
(2) если имеется в виду
HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates и HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates То доступ с наследованием на обе ветки проставил, сертификат все равно не видит. |
|||
4
Gleb K
27.07.16
✎
00:51
|
(2) Если смотреть через толстый клиент, то текущему пользователю доступно только хранилище пользователя и сертификат виден, а на хранилище компа выдается ошибка, но если на его ветку в реестре добавить права текущему пользователю и поместить туда сертификат, то ошибки не появляется, но ни одного сертификата в этом хранилище не видно.
Поставил сертификат в хранилище пользователя, сделал запуск пула приложений от имени текущего пользователя, сертификаты хранилища пользователя все-равно не видны. |
|||
5
Gleb K
27.07.16
✎
17:21
|
Up
|
|||
6
Aloex
27.07.16
✎
17:24
|
С местом исполнения не ошибся: клиент-сервер?
|
|||
7
Gleb K
27.07.16
✎
17:27
|
(6) http-сервис вроде исполняется на сервере, при этом используются синхронные вызовы методов, так что вроде контекст правильный.
|
|||
8
Aloex
27.07.16
✎
17:35
|
ну а толстый клиент на клиенте работает.
|
|||
9
Gleb K
27.07.16
✎
17:41
|
Да, с толстым все ок.
|
|||
10
Gleb K
27.07.16
✎
23:08
|
Ап
|
|||
11
Gleb K
28.07.16
✎
10:28
|
Попробовал через CAPICOM, он видит сертификаты, но при попытке подписать (последняя строка в коде) валится с ошибкой "Ошибка при вызове метода контекста (Sign): Произошла исключительная ситуация: Набор ключей не существует". Пул приложений 1С сейчас стартует под локальным пользователем. Этот же код, но в толстом клиенте под локальным пользователем работает без проблем.
// CAPICOM constants CAPICOM_LOCAL_MACHINE_STORE = 1; CAPICOM_CURRENT_USER_STORE=2; CAPICOM_MY_STORE="My"; CAPICOM_OTHER_STORE="AddressBook"; CAPICOM_STORE_OPEN_READ_ONLY=0; CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0; CAPICOM_CERTIFICATE_FIND_TIME_VALID=9; CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY = 2; CAPICOM_ENCODE_BASE64 = 0; CAPICOM_ENCODE_BINARY = 1; //Найдем сертификат в хранилище Store = Новый COMОбъект("CAPICOM.Store"); Store.Open(CAPICOM_LOCAL_MACHINE_STORE,CAPICOM_MY_STORE,CAPICOM_STORE_OPEN_READ_ONLY); Certificate = Store.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH,"A624B6AE158E677113D2FCE3E66E332A342E0A87").item(1); //Инициализируем подписанта Signer = Новый COMОбъект("CAPICOM.Signer"); Signer.Certificate = Certificate; Signer.Options = CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY; //Инициализируем данные для подписи SignedData = Новый COMОбъект("CAPICOM.SignedData"); Строка64=Base64Строка(Новый ДвоичныеДанные(ИмяВременногоФайла)); Строка64=Прав(Строка64,СтрДлина(Строка64)-4); SignedData.Content = Строка64; //SignedData.Content = DataToSign; //Сформируем подпись Подпись = SignedData.Sign(Signer, 1, CAPICOM_ENCODE_BASE64); |
|||
12
Gleb K
28.07.16
✎
18:22
|
Ап
|
|||
13
Gleb K
29.07.16
✎
14:38
|
Попробовал сделать через обертку .Net
В толстом клиенте все работает. Из модуля http-сервиса пула приложений запускаемого от этого же пользователя - падает на первой строке как-будто COM интерфейс не зарегистрирован. БиблиотекаNET = новый COMОбъект("NetObjectToIDispatch45"); X509Certificate2 = БиблиотекаNET.СоздатьОбъект("System.Security.Cryptography.X509Certificates.X509Certificate2","C:\Cert.pfx", "123456"); RSACryptoServiceProvider = X509Certificate2.PrivateKey; UTF8Encoding = БиблиотекаNET.СоздатьОбъект("System.Text.UTF8Encoding"); МассивБайтСообщения = UTF8Encoding.GetBytes(ТелоОтветаXML); CryptoConfig = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.CryptoConfig"); МассивБайтПодписиСообщения = RSACryptoServiceProvider.SignData(МассивБайтСообщения, CryptoConfig.MapNameToOID("SHA1")); Convert = БиблиотекаNET.ПолучитьТип("System.Convert"); ПодписьBase64Строка = Convert.ToBase64String(МассивБайтПодписиСообщения); Интересно это фундаментальные ограничения или какой-то косяк с правами доступа? |
|||
14
Serginio1
29.07.16
✎
14:43
|
Возможно не зарегистрирован. Там нужно в поставке идет RegAsm.bat
который нужно запустить от администратора Внутри %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe "%~dp0NetObjetToIDispatch45.dll" /codebase %SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "%~dp0NetObjetToIDispatch45.dll" /codebase |
|||
15
Serginio1
29.07.16
✎
14:44
|
Ну и посмотреть настройки пула какой .Net FrameWork использует
|
|||
16
Gleb K
29.07.16
✎
14:46
|
(15) Зарегистрирован батником, в толстом клиенте на этой же машине код полностью отрабатывает. А при запуске через пул приложений IIS на вызов http-сервиса - падает.
|
|||
17
Gleb K
29.07.16
✎
14:48
|
(15) В настройках пула 1С рекомендует ставить Без управляемого кода, но я пробовал ставить 4 Net все-равно падает.
|
|||
18
Serginio1
29.07.16
✎
14:49
|
Там 2 строчки одна для 32 разрядного (Толстый клиент)
Вторая для 64 разрядного. Запусти из под cmd |
|||
19
Gleb K
29.07.16
✎
14:50
|
(18) Запускал cmd под админскими правами и оттуда уже батник.
В реестре вроде прописался HKEY_CLASSES_ROOT\CLSID\{8693BBEC-C964-4478-AFCB-E8D15FD8F4F6} |
|||
20
Serginio1
29.07.16
✎
14:51
|
Попробуй для проверки из фонового задания запустить
|
|||
21
Gleb K
29.07.16
✎
14:51
|
Пул приложений 32 разрядный.
|
|||
22
Serginio1
29.07.16
✎
14:52
|
Может прав на папку не хватает?
|
|||
23
Gleb K
29.07.16
✎
14:54
|
(22) Папку с dll ? Права полные для текущего пользователя - в толстом клиенте все отрабатывает, через пул приложений под правами того же текущего пользователя - нет.
|
|||
24
Serginio1
29.07.16
✎
14:55
|
Кстати ProgID DFDADA57-B22C-4276-928A-8B91C9891FF1
Посмотри права DCOM |
|||
25
Gleb K
29.07.16
✎
14:55
|
(20) Спасибо, позже попробую.
|
|||
26
Serginio1
29.07.16
✎
14:57
|
||||
27
Gleb K
29.07.16
✎
14:57
|
(24) Это через оснастку Службы компонентов\Настройка Dcom ?
|
|||
28
Gleb K
29.07.16
✎
14:59
|
(26) У меня база стартует в файловом режиме.
|
|||
29
Gleb K
29.07.16
✎
15:00
|
(26) Политики попробую попозже.
|
|||
30
Serginio1
29.07.16
✎
15:01
|
||||
31
Gleb K
29.07.16
✎
15:08
|
(14) При регистрации он кстати ругался на ключ /codebase но потом написал, что типы успешно зарегистрированы
|
|||
32
Gleb K
29.07.16
✎
15:12
|
(30) У меня в дереве Dcom нет NetObjetToIDispatch45
Дерево смотрю 32 разрядное через mmc comexp.msc /32 |
|||
33
Serginio1
29.07.16
✎
15:41
|
(31) Кстати а в роли от кого запускается 1С стоит галка Automation
|
|||
34
Serginio1
29.07.16
✎
15:47
|
Попробуй установить Привилегированный режим
|
|||
35
Gleb K
29.07.16
✎
15:49
|
Сейчас поставил общие права на объекты Dom и прописал права в локальных политиках, теперь ошибка Отказано в доступе. Но сервер еще не перезагружал.
|
|||
36
Gleb K
29.07.16
✎
15:55
|
(33) Стоит
(34) Не помогло Сейчас опять выдает ошибку Класс не зарегистрирован. |
|||
37
Gleb K
29.07.16
✎
15:57
|
(24) Такой объект тоже зарегистрирован HKEY_CLASSES_ROOT\CLSID\{DFDADA57-B22C-4276-928A-8B91C9891FF1}
|
|||
38
Serginio1
29.07.16
✎
16:03
|
(25) Такое впечатление, что нет у тебя доступа к реестру.
|
|||
39
Serginio1
29.07.16
✎
16:13
|
||||
40
Gleb K
29.07.16
✎
16:13
|
(38) Хочешь прикол?
JS=Новый COMОбъект("MSScriptControl.ScriptControl"); JS.Language="jscript"; JS.Timeout=-1; попытка СтрКода="function SignFile(FileName,Cert,OutFileName) |{ | NET=new ActiveXObject(""NetObjectToIDispatch45""); | return(NET); |} |"; JS.AddCode(СтрКода); БиблиотекаNET=JS.Run("SignFile"); //До сюда код выполняется и в БиблиотекаNET сидит COMОбъект а на следующей строке все падает с ошибкой "Ошибка при вызове метода контекста (СоздатьОбъект): Произошла исключительная ситуация (mscorlib): Адресат вызова создал исключение." X509Certificate2 = БиблиотекаNET.СоздатьОбъект("System.Security.Cryptography.X509Certificates.X509Certificate2","C:\Users\g.kondratyev\Desktop\leader\GKazimut360.pfx", "azimut360"); |
|||
41
Serginio1
29.07.16
✎
16:15
|
Посмотри настройки пула
http://professorweb.ru/my/ASP_NET/sites/level3/3_3.php |
|||
42
Serginio1
29.07.16
✎
16:18
|
Попробуй просто ПолучитьТип
X509Certificate2 =БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.X509Certificate2"); X509Certificate2 = БиблиотекаNET.СоздатьОбъектX509Certificate2,"C:\Users\g.kondratyev\Desktop\leader\GKazimut360.pfx", "azimut360"); А сервис запускаешь от g.kondratyev |
|||
43
Gleb K
29.07.16
✎
16:21
|
(41) Там все вроде ок.
(42) Пул идентити сейчас g.kondratyev |
|||
44
Gleb K
29.07.16
✎
16:25
|
(42) С ПолучитьТип() полет нормальный
|
|||
45
Serginio1
29.07.16
✎
16:28
|
Значит проблема доступа к ,"C:\Users\g.kondratyev\Desktop\leader\GKazimut360.pfx",
Попробуй просто найти файл Можно создать и так X509Certificate2 =БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.X509Certificate2"); Сертификат = БиблиотекаNET.СоздатьОбъект(X509Certificate2,"C:\Users\g.kondratyev\Desktop\leader\GKazimut360.pfx", "azimut360"); |
|||
46
Gleb K
29.07.16
✎
16:30
|
(45) На второй строке этот код вызывает исключение.
|
|||
47
Gleb K
29.07.16
✎
16:32
|
(45) Права на файл у g.kondratyev полные
|
|||
48
Serginio1
29.07.16
✎
16:34
|
Понятно. Проверь просто
файл=Новый Файл(путь); Файл.Существует(); |
|||
49
Gleb K
29.07.16
✎
16:38
|
(48) Да, вы правы Файл.Существует() = Ложь
в чем может быть причина? |
|||
50
Serginio1
29.07.16
✎
16:44
|
Mожет С русская?
|
|||
51
Gleb K
29.07.16
✎
16:52
|
(50) Путь копипастил с проводника и в толстом клиенте он работает :(
|
|||
52
Gleb K
29.07.16
✎
17:03
|
Переместил файл поближе и перевел в нижний регистр: c:\1cbase\gk.pfx
Теперь файл существует, но при попытке X509Certificate2 = БиблиотекаNET.СоздатьОбъект(X509Certificate2, ФайлКлюча, Пароль); падает: "Ошибка при вызове метода контекста (СоздатьОбъект): Произошла исключительная ситуация (NetObjetToIDispatch45): Ссылка на объект не указывает на экземпляр объекта." |
|||
53
Gleb K
29.07.16
✎
17:03
|
(52) аа, походу понял косяк
|
|||
54
Gleb K
29.07.16
✎
17:06
|
Исправил, но код
JS=Новый COMОбъект("MSScriptControl.ScriptControl"); JS.Language="jscript"; JS.Timeout=-1; СтрКода="function SignFile(FileName,Cert,OutFileName) |{ | NET=new ActiveXObject(""NetObjectToIDispatch45""); | return(NET); |} |"; JS.AddCode(СтрКода); БиблиотекаNET=JS.Run("SignFile"); X509Cert2 = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.X509Certificate2"); X509Certificate2 = БиблиотекаNET.СоздатьОбъект(X509Cert2, ФайлКлюча, Пароль); все-равно падает на последней строке "Ошибка при вызове метода контекста (СоздатьОбъект): Произошла исключительная ситуация (mscorlib): Адресат вызова создал исключение."" |
|||
55
Serginio1
29.07.16
✎
17:11
|
Ты кстати
врап=новый COMОбъект("NetObjectToIDispatch45"); врап.ВыводитьСообщениеОбОшибке=ложь; И можно Попытка X509Certificate2 = БиблиотекаNET.СоздатьОбъект(X509Cert2, ФайлКлюча, Пароль); исключение Сообщить(Врап.ВСтроку(Врап.ПоследняяОшибка)); конецПопытки |
|||
56
Serginio1
29.07.16
✎
17:12
|
А что, за ошибка?
|
|||
57
Gleb K
29.07.16
✎
17:20
|
(56)
ОшибкаNET = БиблиотекаNET.ВСтроку(БиблиотекаNET.ПоследняяОшибка); содержит строку "неопределено" |
|||
58
Serginio1
29.07.16
✎
17:25
|
А
Сообщить(ОписаниеОшибки()); |
|||
59
Gleb K
29.07.16
✎
17:25
|
(58) Ошибка при вызове метода контекста (СоздатьОбъект): Произошла исключительная ситуация (mscorlib): Адресат вызова создал исключение.
|
|||
60
Serginio1
29.07.16
✎
17:29
|
||||
61
Serginio1
29.07.16
✎
17:34
|
||||
62
Gleb K
29.07.16
✎
17:37
|
(61) Serginio1 огромное спасибо за помощь, попробую импорт завтра, а также через X509Store.
|
|||
63
Serginio1
29.07.16
✎
17:40
|
Для флагов есть OR
Например Код на C# new X509Certificate2(fileName, keyPassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable) Код на 1С Сертификат=X509Certificate2(fileName, keyPassword,Врап.OR( X509KeyStorageFlags.MachineKeySet, X509KeyStorageFlags.PersistKeySet, X509KeyStorageFlags.Exportable)); |
|||
64
Serginio1
29.07.16
✎
17:42
|
Вернее
Сертификат=Врап.СоздатьОбъект(X509Cert2,fileName, keyPassword,Врап.OR( X509KeyStorageFlags.MachineKeySet, X509KeyStorageFlags.PersistKeySet, X509KeyStorageFlags.Exportable)); |
|||
65
Gleb K
30.07.16
✎
17:37
|
(30) Перезагрузил сервер, настройки прав не решили ситуацию.
|
|||
66
Gleb K
30.07.16
✎
17:40
|
Пробую сейчас через хранилище
//Инициализируем перечисления StoreLocation = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.StoreLocation"); //LocalMachine, CurrentUser OpenFlags = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.OpenFlags"); X509FindType = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.X509FindType"); //Инициализируем класс хранилища X509Store = БиблиотекаNET.СоздатьОбъект("System.Security.Cryptography.X509Certificates.X509Store", "My", StoreLocation.LocalMachine); //Открываем хранилище X509Store.Open(OpenFlags.ReadWrite);//ReadOnly //Находим сертификат Certificates = X509Store.Certificates.Find(X509FindType.FindByThumbprint, "A624B6AE158E677113D2FCE3E66E332A342E0A87", Истина); Enumerator = Certificates.GetEnumerator(); Enumerator.MoveNext(); X509Certificate2 = Enumerator.Current; RSACryptoServiceProvider = X509Certificate2.PrivateKey; //На последней строке код падает Ошибка при получении значения атрибута контекста (PrivateKey): Неизвестная ошибка System.Reflection.TargetInvocationException: Адресат вызова создал исключение. ---> System.Security.Cryptography.CryptographicException: Не удается найти указанный файл. |
|||
67
Serginio1
30.07.16
✎
23:12
|
Попробуй 63
|
|||
68
Serginio1
30.07.16
✎
23:13
|
||||
69
Gleb K
01.08.16
✎
00:16
|
(68) Хорошая статья, но странно это, т.к. у меня в пуле приложений стоит Загрузить профиль пользователя = True, т.е. с этой настройкой должно работать создание объекта сертификата из файла, но нет.
Далее предлагается поместить сертификат в хранилище компа, дать права на него пользователю под которым запускается пул, и достать его из хранилища, что собственно я успешно и делаю, но при обращении к закрытому ключу объекта сертификат получаю грабли. |
|||
70
Gleb K
01.08.16
✎
00:29
|
(63) Эврика! Рабочим оказался следующий код:
JS=Новый COMОбъект("MSScriptControl.ScriptControl"); JS.Language="jscript"; JS.Timeout=-1; СтрКода="function GetNet() |{ | NET=new ActiveXObject(""NetObjectToIDispatch45""); | return(NET); |} |"; JS.AddCode(СтрКода); БиблиотекаNET=JS.Run("GetNet"); X509Certificate2 = БиблиотекаNET.СоздатьОбъект("System.Security.Cryptography.X509Certificates.X509Certificate2"); X509KeyStorageFlags = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.X509Certificates.X509KeyStorageFlags"); X509Certificate2.import(ПолноеИмяФайлаКлюча, Пароль, БиблиотекаNET.OR(X509KeyStorageFlags.MachineKeySet, X509KeyStorageFlags.PersistKeySet, X509KeyStorageFlags.Exportable)); RSACryptoServiceProvider = X509Certificate2.PrivateKey; UTF8Encoding = БиблиотекаNET.СоздатьОбъект("System.Text.UTF8Encoding"); МассивБайтСообщения = UTF8Encoding.GetBytes(ТелоОтветаXML); CryptoConfig = БиблиотекаNET.ПолучитьТип("System.Security.Cryptography.CryptoConfig"); МассивБайтПодписиСообщения = RSACryptoServiceProvider.SignData(МассивБайтСообщения, CryptoConfig.MapNameToOID("SHA1")); Convert = БиблиотекаNET.ПолучитьТип("System.Convert"); ПодписьBase64Строка = Convert.ToBase64String(МассивБайтПодписиСообщения); Serginio1 огромное спасибо за участие, хотя еще мне нужно сделать проверку подписи входящего запроса, но если будут проблемы напишу сюда и надеюсь не откажите еще раз помочь. |
|||
71
Serginio1
01.08.16
✎
09:35
|
(70) Посмотри ЭЦП, Сертификат, Подпись. Продолжение.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |