Невозможно использовать сертификат для входа на сайт через com-interop в Windows 10 1809 - PullRequest
0 голосов
/ 06 февраля 2019

Код C # ниже, который входит на веб-сайт,

  • Работает при вызове на компьютере A из Excel 2010 VBA через com-interop
  • Работает при вызове на компьютере Bиз консольного приложения C #, но
  • Сбой при вызове на компьютер B из Excel 2010 VBA через com-interop

Основное различие между компьютером A и компьютером B состоит в том, что компьютер A имеетWindows 10 версии 1803, тогда как компьютер B имеет Windows 10 версии 1809. Оба компьютера имеют Studio 2017, и во всех случаях целевой .Net Framework является 4.6.2.

using System;
using System.Runtime.InteropServices;
using System.IO;

[Guid("97E1D9DB-8478-4E56-9D6D-26D8EF13B100")]
[ComVisible(true)]
public interface IToExcel {
    string Do();
}

[Guid("BBF87E31-77E2-46B6-8093-1689A144BFC6")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Main : IToExcel {
    private const string XAPP_ID = "...";
    private const string USERNAME = "...";
    private const string PASSWORD = "...";
    private const string CERT_FILE = @"...";
    private const string CERT_PASSWORD = "...";
    private const string WEBSITE = "https:// ...";

    public string Do() {
        System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(WEBSITE));
        request.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate;
        request.Method = "POST";
        request.Accept = "application/json";
        request.Timeout = request.ReadWriteTimeout = 20000;
        request.ContentType = "application/x-www-form-urlencoded";
        request.UseDefaultCredentials = true;
        request.Proxy = null;
        // setup headers
        System.Net.WebHeaderCollection whc = new System.Net.WebHeaderCollection {
            { "X-Application", XAPP_ID },
            { System.Net.HttpRequestHeader.AcceptCharset, "utf-8" },
            { System.Net.HttpRequestHeader.AcceptEncoding, "gzip,deflate" }
        };
        request.Headers.Add(whc);
        // setup certificate
        System.Security.Cryptography.X509Certificates.X509Certificate2 m_x509certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(CERT_FILE, CERT_PASSWORD);
        request.ClientCertificates.Add(m_x509certificate);
        // do call
        using (Stream stream = request.GetRequestStream()) {
            using (StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Default)) {
                writer.Write("username=" + USERNAME + "&password=" + PASSWORD);
            }
        }
        string responseData = string.Empty;
        using (System.Net.WebResponse response = request.GetResponse()) {
            using (Stream responseStream = response.GetResponseStream()) {
                using (StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8)) {
                    responseData = reader.ReadToEnd();
                }
            }
        }
        return responseData;
    }

}

Во всех случаях возвращается небольшой объект JSON, где у объекта JSON есть поле с именем loginStatus.Когда это работает, "loginStatus" = "УСПЕХ", но когда это не удается "loginStatus" = "CERT_AUTH_REQUIRED".

Я пытался просмотреть все настройки в System.Net.ServicePointManager, но во всех случаях настройки былито же самое:

  • ReusePort: False
  • ServerCertificateValidationCallback:
  • DnsRefreshTimeout: 120000
  • EnableDnsRoundRobin: False
  • Expect100Продолжить: True
  • UseNagleAlgorithm: True
  • MaxServicePointIdleTime: 100000
  • DefaultConnectionLimit: 2
  • MaxServicePoints: 0
  • Протокол безопасности: Tls, Tls11, Tls12
  • CheckCertificateRevocationList: False
  • EncryptionPolicy: RequireEncryption

Кроме того, я не знаю, что еще проверить.Обновление с .Net 4.6.2 до 4.7.1 не дало никакого эффекта, результаты были такими же.

Я задавался вопросом, является ли это ошибкой в ​​Windows 1809, но так как она работает при вызове непосредственно в .Netконсольное приложение, я полагаю, это небольшая проблема конфигурации.Может ли кто-нибудь помочь мне получить эту работу из Excel 2010 на компьютере B?

Обновление 8 февраля 2019

Как указано в комментариях, я использовал Fiddler для просмотраструктура вызовов https, которые совершаются на веб-сайт.Два из них работают одинаково, а тот, который не работает, выглядит немного иначе:

Вызовы, которые работают, OK

  • Расширение TLS ec_point_formats = uncompressed [0x0]
  • TLSРасширение encrypt_then_mac (RFC7366) не указано
  • Расширение TLS renegotiation_info = 0
  • Шифр ​​TLS_EMPTY_RENEGOTIATION_INFO_SCSV не указано

Ошибка вызова

  • ec_point_formats = несжатый [0x0], ansiX962_compressed_prime [0x1], ansiX962_compressed_char2 [0x2]

Но теперь у меня есть эта информация, я не уверен, поможет ли она.Возможно, что работающие вызовы генерируются одним и тем же кодом низкого уровня (несмотря на то, что они выполняются в разных версиях Windows 10), а сбойный вызов генерируется другим кодом низкого уровня.

Обновление 10 февраля 2019

При вызове из Excel через com-interop я заставил код выполнять EXE в новом домене приложений вместо прямого вызова кода входа.И когда я это сделал, EXE-файл не работал и выдал тот же вывод, как если бы я вызывал код входа в систему напрямую.

Ниже представлено окно вывода Visual Studio, в котором показан порядок, в котором находятся библиотеки DLL.загружается при запуске EXE-файла, непосредственно перед выполнением кода входа.Самое большое различие между успешными сценариями и неудачным сценарием заключается в том, что неудачный сценарий никогда не загружает C: \ Windows \ System32 \ ncryptprov.dll.Кто-нибудь знает, что вызывает загрузку этой DLL?

(Win32): загружен 'C: \ Windows \ System32 \ msisip.dll'

(Win32): Загружено 'C: \ Windows \ System32 \ coml2.dll' --- ЗАГРУЖЕНО РАНЬШЕ ИЗ EXCEL

(Win32): загружено 'C: \ Windows \ System32 \ wshext.dll'

(Win32): загружено 'C: \ Windows \ System32 \ AppxSip.dll'

(Win32): загружено 'C: \ Windows \ System32 \ tdh.dll'

(Win32)): Загружено 'C: \ Windows \ System32 \ xmllite.dll'

(Win32): загружено 'C: \ Windows \ System32 \ OpcServices.dll'

(Win32): загружено 'C: \ Windows \ System32 \ mintdh.dll '

(Win32): загружено' C: \ Windows \ System32 \ urlmon.dll '--- ЗАГРУЗЕНО РАНЬШЕ ИЗ EXCEL

(Win32): Загружено 'C: \ Windows \ System32 \ mintdh.dll'

(Win32): выгружено 'C: \ Windows \ System32 \ mintdh.dll'

(Win32): загружено 'C: \ Windows \ System32 \ iertutil.dll '--- ЗАГРУЖЕННЫЙ РАНЬШЕ ИЗ EXCEL

(Win32): Загружен' C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ pwrshsip.dll '

(Win32): загружен 'C: \ Windows \ System32 \ EsdSip.dll'

(Win32): загружен 'C: \ Windows \ System32 \ userenv.dll' --- ЗАГРУЗЕН РАНЬШЕ ИЗ EXCEL

(Win32): загружено 'C: \ Windows \ System32 \ dpapi.dll'

(Win32): загружено 'C: \ Windows \ System32 \ dnsapi.dll'

(Win32): загружен 'C:\ Windows \ System32 \ rasadhlp.dll '

(Win32): загружен' C: \ Windows \ System32 \ FWPUCLNT.DLL '

(Win32): загружен' C: \ Windows \ System32\ secur32.dll '

(Win32): загружено' C: \ Windows \ System32 \ sspicli.dll '--- ЗАГРУЖЕНО РАНЬШЕ ИЗ EXCEL

(Win32): загружено' C: \Windows \ System32 \ schannel.dll '

(Win32): загружен' C: \ Windows \ System32 \ mskeyprotect.dll '

(Win32): загружен' C: \ Windows \ System32 \ncrypt.dll '

(Win32): загружен' C: \ Windows \ System32 \ ntasn1.dll '

(Win32): загружен' C: \ Windows \ System32 \ ncryptprov.dll '--- НИКОГДА НЕ ЗАГРУЖАЕТСЯ ИЗ EXCEL

(Win32): загружен 'C: \ Windows \ System32 \ ncryptsslp.dll'

На этом этапе код C # выполняется

Обновление 12 февраля 2019 года

Большое спасибо Саймону Мурье за то, что он рассказал мне, как настроить диагностику System.Net.При выполнении диагностики на компьютере B строки «Информация о System.Net», которые получают выходные данные для двух случаев, начинаются одинаково, но в конечном итоге есть разница.Это вывод из файла Console EXE на компьютере B (т. Е. Случай, который работает):

System.Net Information: 0 : [35268] Current OS installation type is 'Client'.
System.Net Information: 0 : [35268] RAS supported: True
System.Net Information: 0 : [35268] Associating HttpWebRequest#21454193 with ServicePoint#34640832
System.Net Information: 0 : [35268] Associating Connection#43332040 with HttpWebRequest#21454193
System.Net Information: 0 : [35268] Connection#43332040 - Created connection from XXX.XXX.XXX.XXX:53002 to YYY.YYY.YYY.YYY:443.
System.Net Information: 0 : [35268] TlsStream#54444047::.ctor(host=<TargetWebSite>, #certs=1, checkCertificateRevocationList=False, sslProtocols=Tls12)
System.Net Information: 0 : [35268] Associating HttpWebRequest#21454193 with ConnectStream#20234383
System.Net Information: 0 : [35268] HttpWebRequest#21454193 - Request: POST /api/certlogin HTTP/1.1
System.Net Information: 0 : [35268] ConnectStream#20234383 - Sending headers
System.Net Information: 0 : [35268] SecureChannel#47891719::.ctor(hostname=<TargetWebSite>, #clientCertificates=1, encryptionPolicy=RequireEncryption)
System.Net Information: 0 : [35268] Enumerating security packages:
System.Net Information: 0 : [35268]     Negotiate
System.Net Information: 0 : [35268]     NegoExtender
System.Net Information: 0 : [35268]     Kerberos
System.Net Information: 0 : [35268]     NTLM
System.Net Information: 0 : [35268]     TSSSP
System.Net Information: 0 : [35268]     pku2u
System.Net Information: 0 : [35268]     CloudAP
System.Net Information: 0 : [35268]     WDigest
System.Net Information: 0 : [35268]     Schannel
System.Net Information: 0 : [35268]     Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [35268]     Default TLS SSP
System.Net Information: 0 : [35268]     CREDSSP
System.Net Information: 0 : [35268] SecureChannel#47891719 - Attempting to restart the session using the user-provided certificate: [Version]
System.Net Information: 0 : [35268] SecureChannel#47891719 - Left with 1 client certificates to choose from.
System.Net Information: 0 : [35268] SecureChannel#47891719 - Trying to find a matching certificate in the certificate store.
System.Net Information: 0 : [35268] SecureChannel#47891719 - Locating the private key for the certificate: [Version]
System.Net Information: 0 : [35268] SecureChannel#47891719 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [35268] SecureChannel#47891719::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Tls12Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [35268] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)
System.Net Information: 0 : [35268] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = <TargetWebSite>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [35268] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=184, returned code=ContinueNeeded).
System.Net Information: 0 : [35268] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 227c85a89b0:2449d0deff0, targetName = <TargetWebSite>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [35268] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=CredentialsNeeded).

Однако при запуске из Excel 2010 через com-interop вместо последних 4 строк InitializeSecurityContext6 строк InitializeSecurityContext выглядят следующим образом:

System.Net Information: 0 : [39988] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = <TargetWebSite>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [39988] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=184, returned code=ContinueNeeded).
System.Net Information: 0 : [39988] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 8a8e2f0:2449d0def90, targetName = <TargetWebSite>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [39988] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded).
System.Net Information: 0 : [39988] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 8a8e2f0:2449d0def90, targetName = <TargetWebSite>, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [39988] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=ContinueNeeded).

Первые две строки InitializeSecurityContext идентичны, поэтому, по-видимому, принципиальное различие заключается в третьей строке InitializeSecurityContext, где консоль EXE-файла имеет

context = 227c85a89b0: 2449d0deff0

но неудачный запуск через executino com-interop имеет

context = 8a8e2f0: 2449d0def90

После этого все выглядит не так, как можно было бы ожидать,Кто-нибудь знает, что означает эта разница и как ее устранить, чтобы выполнение com-interop осуществлялось так же, как выполнение com-interop?

Обновление 13 февраля 2019 г.

Я разместил больше результатов диагностики на форуме MSDN .

1 Ответ

0 голосов
/ 13 февраля 2019

Сосредоточив внимание на проблеме консоли C # и Excel 2010 (тот же компьютер, оба выполняются как 64-разрядные процессы), трассировки были добавлены, как описано здесь: https://stackoverflow.com/a/25683524/403671

Первоначальные трассировки из Excel и консоли:точно так же (см. вопрос для более подробной информации).Но последние следы (опубликованные в MSDN) показывают это:

Консоль:

System.Net Information: 0 : [35268] Remote certificate: [Version] V3
[ Lots of lines describing a certificate with [Subject]=<TargetWebSite>, [Issuer]=HydrantID SSL ICA G2, etc]
System.Net Information: 0 : [35268] SecureChannel#47891719 - Remote certificate was verified as valid by the user.    

Excel:

System.Net Information: 0 : [39988] Remote certificate: [Version] V3
[ Lots of lines describing a certificate with [Subject]=<TargetWebSite>, [Issuer]=Kaspersky, etc]
System.Net Information: 0 : [39988] SecureChannel#2383799 - Remote certificate was verified as valid by the user.

Показывает, что сертификат, используемый в Excel, теперь выданот Kaspersky, который оказывается антивирусным продуктом, работающим на ПК.Фактически, это функция безопасности продукта Kaspersky для перехвата связи , и это вызывает многочисленные проблемы, такие как, например, KIS, вмешивающийся в Git .

Когда-то этовирус удаляется все работает как положено.

...