HTTPS über WinHttp funktioniert mit TLS1.1 nicht mehr

  • Hallo,

    ich hoffe, mir kann jemand bei meinem WinHTTP-Secure-Problem helfen.
    Bisher funktionierte bei HTTPS-Requests mein Code (siehe Spoiler). Jetzt wurde die Verschlüsselung auf TLS1.1 geändert, und der _WinHttpSendRequest läuft auf einen Fehler. Wo kann ich die Verschlüsselung anpassen?
    Im Internet finde ich zu dem Thema den Hinweis, das die Security-Optionen mit Hilfe der Funktionen WinHttpQueryOption bzw. WinHttpSetOption zu ändern sind.

    Doku-Ausschnitt:
    WINHTTP_OPTION_SECURE_PROTOCOLS

    Sets an unsigned long integer value that specifies which secure
    protocols are acceptable. By default only SSL3 and TLS1 are enabled.
    Can by a combination of one or more of the following values.


    WINHTTP_FLAG_SECURE_PROTOCOL_ALL
    The Secure Sockets Layer (SSL) 2.0, SSL 3.0, and Transport Layer Security (TLS) 1.0 protocols can be used.

    WINHTTP_FLAG_SECURE_PROTOCOL_SSL2
    The SSL 2.0 protocol can be used.

    WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
    The SSL 3.0 protocol can be used.

    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
    The TLS 1.0 protocol can be used.

    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1
    The TLS 1.1 protocol can be used.

    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
    The TLS 1.2 protocol can be used.


    Wo kann ich diese Werte setzen? In den WinHttpConstants finde ich keine entsprechenden Konstanten.

    Vielen Dank schon mal im voraus :)


    Spoiler anzeigen


    Local $hRequest = _WinHttpOpenRequest($hConnect, "GET", "https://xyz.de", Default, Default, Default, $WINHTTP_FLAG_SECURE)

    _WinHttpSetOption($hRequest, $WINHTTP_OPTION_SECURITY_FLAGS, BitOR($SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_UNKNOWN_CA))

  • Die Konstante verwende ich nicht, da ich mit _WinHttpCrackUrl() arbeite. Dort hole ich mir unter anderem auch den Port. Ich habe mal meinen gesamten Quellcode angehängt. Wie gesagt: Bis vor ein paar Tagen lief das ganze mit Http und Https fehlerfrei.

    Der Fehler tritt beim _WinHttpSendRequest() auf. Ich gehe allerdings davon aus, das der Fehler im _WinHttpOpenRequest() liegt, bzw. die
    _WinHttpSetOption() ergänzt oder geändert werden müssen.

    Ist evtl. ist die WinHttp.au3 incl. der WinHttpConstants.au3 für TLS1.1 gar nicht aufgebaut. Ich habe mir die neueste WinHttp-Version gezogen (1.6.3.4). Oder muss ich eine spezielle WinHttp.dll nutzen?
    Ich bin leider keine WinHttp-Experte, und habe mir bisher alles selbst angelesen. Aber hier bin ich mit meinem Latein am Ende.

    Hoffentlich hat noch jemand eine Idee!!!

    [autoit]


    $sSendUrl = WinHttpFunction($sURL, $searchfor, $msTimeout)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func WinHttpFunction($sWinHttpUrl, $sWinHttpSearchFor = "", $iWinHttpTimeout = 0)

    [/autoit][autoit][/autoit][autoit]

    ; Init
    $sHTMLResponseHeader = "" ;Leeren des Inhalts aus dem letzten Durchlauf (Gefüllt durch _WinHttpQueryHeaders)
    $sResponseHTMLCode = "" ;Leeren des Inhalts aus dem letzten Durchlauf (Gefüllt durch _WinHttpReadData)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; 1. Cracking URL
    ; Die Url wird in die relevanten String zerlegt
    ; Wichtig: Als Parameter ist $ICU_DECODE mitzugeben, da sonst Sonderzeichen geändert werden
    Local $aUrl = _WinHttpCrackUrl($sWinHttpUrl, $ICU_DECODE)
    ;~ _ArrayDisplay($aUrl, "_WinHttpCrackUrl()")

    [/autoit][autoit][/autoit][autoit]

    ; Beispiel: http://GLPBAPIBW001-web.in.gad.de/ptlweb/WebPortal?bankid=7613
    Local $sSchemeName = $aUrl[0] ;http oder https Beispiel ==> http
    Local $sScheme = $aUrl[1] ;1 für http oder 2 für https Beispiel ==> 1
    Local $sServer = $aUrl[2] ;Server-Name Beispiel ==> Serverxxx.xyz.de
    Local $sPort = $aUrl[3] ;Port (evtl. abweichender 80/443-Port) Beispiel ==> 80
    Local $sCrackUser = $aUrl[4] ;UserName Beispiel ==> leer
    Local $sCrackPsw = $aUrl[5] ;Password Beispiel ==> leer
    Local $sUrlAdd = $aUrl[6] ;Url-Pfad Beispiel ==> /ptlweb/WebPortal
    Local $sAdditional = $aUrl[7] ;Zusatzinformationen. Dieser kann auch leer sein Beispiel ==> ?serverID=nnn

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; 2. Initializes the use of WinHttp functions and returns a WinHttp-session handle.
    ;~ Success - Returns valid session handle.
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    Local $hOpen = _WinHttpOpen()
    if $hOpen = 0 then return "Fehler beim Initialisieren der WinHttp-Session [_WinHttpOpen]"

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; 3. Set timeouts in Milliseconds
    ;~ Initial values are:
    ;~ - $iResolveTimeout = 0
    ;~ - $iConnectTimeout = 60000
    ;~ - $iSendTimeout = 30000
    ;~ - $iReceiveTimeout = 30000
    ;~ Hinweis: Der ResolveTimeout wird nicht überschrieben. SendTimeout und ReceiveTimeout übernehmen den übergebenen Wert.
    ;~ Der ConnectionTimeout wird mit 2 multipliziert (adäquat zu den Initial-Werten)
    ;~ Die geänderten Werte gelten nur für diesen WinHttpOpen!
    ;~ Wird kein Wert übergeben, dann hat $WinHttpTimeout den Wert 0
    if $iWinHttpTimeout <> 0 then
    Local $iResolveTimeout = 0
    Local $iConnectTimeout = $iWinHttpTimeout * 2
    Local $iSendTimeout = $iWinHttpTimeout
    Local $iReceiveTimeout = $iWinHttpTimeout

    [/autoit][autoit][/autoit][autoit]

    _WinHttpSetTimeouts($hOpen, $iResolveTimeout, $iConnectTimeout, $iSendTimeout, $iReceiveTimeout)
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ 4. Specifies the initial target server of an HTTP request and returns connection handle to an HTTP session for that initial target.
    ;~ Success - Returns a valid connection handle to the HTTP session
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    ;~ es ist nur der Server anzugeben, nicht die Url
    Local $hConnect = _WinHttpConnect($hOpen, $sServer, $sPort)
    if $hConnect = 0 then
    ; Close handles
    _WinHttpCloseHandle($hOpen)
    return "Fehler beim Connecten der WinHttp-Session zum Server [_WinHttpConnect]"
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ 5. Creates an HTTP request handle.
    ;~ Success - Returns valid session handle.
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    ;~ Mit der Aktion GET und den URL-Zusatzparametern erhält man den HTML-Sourcecode und den Response-Header
    ;~ HTTPS: Bei HTTPS-Verbindungen muss der Parameter "$WINHTTP_FLAG_SECURE" mitgegeben werden.
    ;~ Beschreibung Microsoft msdn: Uses secure transaction semantics. This translates to using Secure Sockets Layer (SSL)/Transport Layer Security (TLS).
    if $sScheme = 2 then
    Local $hRequest = _WinHttpOpenRequest($hConnect, "GET", $sUrlAdd & $sAdditional, Default, Default, Default, $WINHTTP_FLAG_SECURE) ;==> https

    [/autoit][autoit][/autoit][autoit]

    ;~ Internet-Optionen so setzen, das unbekannte Zertifizierungsstellen und ungültige Zertifikate ignoriert werden.
    ;~ $SECURITY_FLAG_IGNORE_CERT_CN_INVALID = Allows an invalid common name in a certificate; that is,
    ;~ the server name specified by the application does not match the common name
    ;~ in the certificate. If this flag is set, the application does not receive a
    ;~ WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID callback.
    ;~ $SECURITY_FLAG_IGNORE_UNKNOWN_CA = Allows an invalid certificate authority. If this flag is set, the application
    ;~ does not receive a WINHTTP_CALLBACK_STATUS_FLAG_CERT_INVALID_CA callback.
    _WinHttpSetOption($hRequest, $WINHTTP_OPTION_SECURITY_FLAGS, BitOR($SECURITY_FLAG_IGNORE_CERT_CN_INVALID, $SECURITY_FLAG_IGNORE_UNKNOWN_CA))
    Else
    Local $hRequest = _WinHttpOpenRequest($hConnect, "GET", $sUrlAdd & $sAdditional) ;==> http
    EndIf

    [/autoit][autoit][/autoit][autoit]

    if $hRequest = 0 then
    ; Close handles
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Fehler beim Aufbauen des HTTP-Requests [_WinHttpOpenRequest]"
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ 6. Sends the specified request to the HTTP server.
    ;~ Success - Returns 1.
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    ;~ Hinweis: Dieser Fehler tritt unter anderem auf, wenn keine FW-Freischaltung exisitiert. Testen mit Telnet.
    Local $send = _WinHttpSendRequest($hRequest)
    if $send = 0 then
    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Fehler beim Senden des WinHttp-Requests [_WinHttpSendRequest]"
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; 7. Waits to receive the response to an HTTP request initiated by WinHttpSendRequest().
    ;~ Success - Returns 1.
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    ;~ Hinweis: Bei HTTPS-Verbindungen tritt dieser Fehler auf, wenn das Zertifikat nicht verfügbar ist.
    Local $resp = _WinHttpReceiveResponse($hRequest)
    if $resp = 0 then
    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Fehler oder Timeout beim Warten auf den HTTP-Response [_WinHttpReceiveResponse]"
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ 8. Retrieves header information associated with an HTTP request.
    ;~ Success - Returns string that contains header.
    ;~ - @extended is set to the index of the next header
    ;~ Failure - Returns empty string and sets @error:
    ;~ 1 - DllCall failed
    ;~ Auslesen des Response-Status des Response-Headers (z.B.: HTTP/1.1 200 OK). Die ausgelesenen Informationen befinden sich in der Variable sHeader
    $sHTMLResponseHeader = _WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_RAW_HEADERS) ; ...get full header
    if @error = 1 then
    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Fehler: Der HTML-Response-Header konnte nicht ausgelesen werden [_WinHttpQueryHeaders]"
    EndIf

    [/autoit][autoit][/autoit][autoit]

    $LogText = "HTTP-Response-Code ==> "& $sHTMLResponseHeader
    Call("LogMsg", $LogText, "Info")

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; 9. Returns the availability to be read with _WinHttpReadData().
    ;~ Success - Returns 1 if data is available.
    ;~ - Returns 0 if no data is available.
    ;~ - @extended receives the number of available bytes.
    ;~ Failure - Returns 0 and sets @error:
    ;~ 1 - DllCall failed
    Local $dataexist = _WinHttpQueryDataAvailable($hRequest)
    if $dataexist = 0 then
    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Fehler: Der HTML-Response konnte nicht ausgelesen werden [_WinHttpQueryDataAvailable]"
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ 10. Reads data from a handle opened by the _WinHttpOpenRequest() function.
    ;~ Success - Returns data read.
    ;~ - @extended receives the number of bytes read.
    ;~ Auslesen des HTML-Codes. Der ausgelesene Code befindet sich in der globalen Variablen $sResponseHTMLCode
    Local $sChunk
    While 1
    $sChunk = _WinHttpReadData($hRequest)
    If @error Then ExitLoop
    $sResponseHTMLCode &= $sChunk
    WEnd

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ Check if a string fits a given regular expression pattern.
    ;~ Returns 1 (matched) or 0 (no match)
    If $sWinHttpSearchFor <> "" then
    If StringRegExp($sResponseHTMLCode, $sWinHttpSearchFor, 0) = 0 then
    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)
    return "Der Suchtstring ["& $sWinHttpSearchFor &"] wurde nicht gefunden."
    EndIf
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)

    [/autoit][autoit][/autoit][autoit]

    return "success"

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit]

    Einmal editiert, zuletzt von tamalugo (22. November 2013 um 08:56) aus folgendem Grund: Ich habe noch folgende Info vergessen: Der Fehler tritt beim _WinHttpSendRequest() auf. Ich gehe allerdings davon aus, das der Fehler im _WinHttpOpenRequest() liegt, bzw. die _WinHttpSetOption() ergänzt oder geändert werden müssen. So, das wars jetzt aber:-)