die iOS-Push-Benachrichtigungen (APNs) über GÄ SSL-Handshake-Fehler

Ich bin versucht zu zeigen, proof-of-concept für iOS-Push-Benachrichtigungen aus einer Google AppEngine Anwendung-Instanz, die mit dieser RPC-handler…

PAYLOAD = {'aps': {'alert':'Push!','sound':'default'}}
TOKEN = '[...]'


class APNsTest(BaseRPCHandler):

  def get(self, context, name):
    self._call_method(context, name)

  def send_push(self):

    # certificate files
    filename = 'VisitorGuidePush'
    abs_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../archive/certificate'))
    ca_certs = os.path.abspath(os.path.join(abs_path, '%s.ca'%filename))
    certfile = os.path.abspath(os.path.join(abs_path, '%s.crt'%filename))
    keyfile = os.path.abspath(os.path.join(abs_path, '%s.key'%filename))

    # serialize payload
    payload = json.dumps(PAYLOAD)

    # APNS server address...
    # apns_address = ('api.development.push.apple.com', 443) # Development server
    # apns_address = ('api.development.push.apple.com', 2197) # Development server
    # apns_address = ('api.push.apple.com', 443) # Production server
    apns_address = ('api.push.apple.com', 2197) # Production server

    # a socket to connect to APNS over SSL
    _sock = socket.socket()
    _ssl = ssl.wrap_socket(_sock, keyfile=keyfile,
                                  certfile=certfile,
                                  server_side=False,
                                  cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_version=ssl.PROTOCOL_TLSv1,
                                  ca_certs=ca_certs)
    _ssl.connect(apns_address)

    # Generate a notification packet
    token = binascii.unhexlify(TOKEN)
    fmt = '!cH32sH{0:d}s'.format(len(payload))
    cmd = '\x00'
    message = struct.pack(fmt, cmd, len(token), token, len(payload), payload)

    _ssl.write(message)
    _ssl.close()

    return self.response_result(PAYLOAD)

Und benötigen Hilfe bei der Lösung dieses Fehlers bei der Ausführung „_ssl.connect(apns_address)“

SSLError: [Errno 1] _ssl.c:507: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

Mein PEM-Datei (abgeleitet von einem .p12) und device-token generiert wurden vor einer Woche durch einen mobile developer für unser team, Vorschläge für die überprüfung dieser wäre hilfreich. Für jetzt glaube ich, gibt es aktuell und gültig.

Während der TLSv1-Protokoll wird angegeben, ich habe bemerkt das handshake-Fehler identifiziert sslv3.

Habe ich versucht, viele Variationen und Kombination von wrap_socket und apns_address, und bin immer angehalten, durch die handshake-Fehler. Das führt mich zu vermuten, dass ein problem mit der Art, wie ich bin, die Anwendung der pem-Zertifikat.

Primäre Referenzen habe ich für wrap_socket sind Mit OpenSSL und TLS/SSL-wrapper für socket-Objekte, nicht zu erwähnen, mehr als ein paar StackOverflow-posts.

Bitte geben Sie Hinweise über das entsprechende keyfile, certfile, und ca_certs Werte und sonstige Beratung oder Ressourcen für GAE basiert APNs Kommunikation. Danke ~

Aktualisiert Frage…

Dem original .p12 wurde validiert mit Drücker, und geteilt über openssl…

openssl pkcs12 -in vgp.p12 -out VisitorGuidePush.key -nodes -nocerts
openssl pkcs12 -in vgp.p12 -out VisitorGuidePush.crt -nodes -nokeys
openssl pkcs12 -in vgp.p12 -out VisitorGuidePush.ca -nodes -cacerts

Ich erhalte eine neue Fehlermeldung, die erscheint, im Zusammenhang mit der ca_certs…

SSLError: [Errno 0] _ssl.c:343: error:00000000:lib(0):func(0):reason(0)

Entfernen der ca_certs Anforderung oder Weitergabe in andere Dateien wie die .p12-oder .crt-im Ergebnis eine Rückkehr zu den ursprünglichen handshake-Fehler.

  • Mit der Pusher – app, die ich bestätigen konnte, dass meine PEM Datei ein problem gab. Nach Erhalt der original .p12-Datei, Schieber war in der Lage, um ein APNs-Verbindung.

 

3 Replies
  1. 1

    Blick in eine Bibliothek benutzen, wie pyapns, das ist, was ich verwendet, um push-Benachrichtigungen arbeiten, die auf GAE. Um zu testen, ob Sie die richtigen key/cert-Datei, können Sie apps verwenden, wie Pusher. Auch weiß ich, dass man SSL-Funktionen auf der GAE müssen Sie zum aktivieren der Abrechnung, also vielleicht ist das das problem. Viel Glück!

    • Die Abrechnung aktiviert ist, überprüft, hat seit einiger Zeit jetzt gewesen. Arbeiten mit Pusher nun, dies ist sehr hilfreich, da die Pusher app ist, die sich über den privaten Schlüssel (sehr hilfreich, feedback).
  2. 1

    Dem entsprechenden support-Dateien beginnen mit Schaffung einer Universellen Push-Benachrichtigung Client-SSL-Zertifikat als p12 Datei.

    Nächsten ist, unter Verwendung von Kommandozeilen-openssl, um eine Analyse der p12 in die gewünschte Zertifikat-und key-Dateien…

    openssl pkcs12 -in VisitorGuide.p12 -out VisitorGuide.key -nodes -nocerts
    openssl pkcs12 -in VisitorGuide.p12 -out VisitorGuide.crt -nodes -nokeys
    openssl pkcs12 -in VisitorGuide.p12 -out VisitorGuide.pem -nodes

    Und schließlich erhalten Sie ein qualifiziertes Zertifikat Authority file (aus Fehlersuche-Push-Benachrichtigungen)

    Zusätzlich zu der SSL-Identität (Zertifikat sowie den zugehörigen privaten
    Schlüssel) erstellt von Mitglied-Zentrum, sollten Sie auch installieren, der Entrust-ZERTIFIZIERUNGSSTELLE
    (2048) root-Zertifikat auf Ihrem provider.

    Entrust.net Certificate Authority (2048) herunterladen ~ entrust_2048_ca.cer

    Beachten Sie, dass jede GAE-Instanz hostet seine eigene Certificate Authority unter /etc/ca-certificates.crt, wie hier beschrieben, Mit OpenSSL.


    Mit diesen Dateien Hinzugefügt, um Ihr Projekt können Sie eine von zwei gleichermaßen gültige ssl-socket-Objekte…

    _ssl = ssl.wrap_socket(_sock, keyfile=VisitorGuide.key,
                                  certfile=VisitorGuide.crt,
                                  server_side=False,
                                  cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_version=ssl.PROTOCOL_TLSv1,
                                  ca_certs=entrust_2048_ca.cer)

    …oder…

    _ssl = ssl.wrap_socket(_sock, certfile=VisitorGuide.pem,
                                  server_side=False,
                                  cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_version=ssl.PROTOCOL_TLSv1,
                                  ca_certs=entrust_2048_ca.cer)

    TLS/SSL-wrapper für socket-Objekte 17.3.4.3. Kombinierte Schlüssel und Zertifikat erklärt, warum beide sind gültige parameter-Optionen.


    Bevor ich der Letzte code-block, ich muss darauf hinweisen, etwas, das über das APNs-Adresse (dies erwies sich als der entscheidende Punkt, dass Sie mir zur Behebung des handshake-Fehler und erhalten eine SSL-Verbindung zwischen GAE und APNs)

    Nach der iOS Developer Library APNs-Provider-API

    Den ersten Schritt in das senden von remote-Benachrichtigung wird eine Verbindung mit den entsprechenden APNs-server:

    Entwicklung server: api.Entwicklung.push.apple.com:443

    Produktions-server: api.push.apple.com:443

    Hinweis: alternativ können Sie die Verwendung von port 2197 bei der Kommunikation mit den APNs. Dies können Sie tun, wenn Sie beispielsweise APNs-Datenverkehr durch die firewall, sondern blockieren andere HTTPS-Datenverkehr.

    Aber es war nicht, bis ich gegraben in den Pusher Quelle, entdeckte ich die APNs Adressen, an die ich anschließen könnte…

    gateway.sandbox.push.apple.com:2195

    gateway.push.apple.com:2195


    Ohne weitere ado…

    class APNsTest(BaseRPCHandler):
    
      def get(self, context, name):
        self._call_method(context, name)
    
      def send_push(self):
    
        # certificate files
        abs_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../cert'))
        pem_file = os.path.abspath(os.path.join(abs_path, 'VisitorGuide.pem'))
        ca_certs = '/etc/ca-certificates.crt'
    
        # APNS server address...
        apns_address = ('gateway.sandbox.push.apple.com', 2195)
        # apns_address = ('gateway.push.apple.com', 2195)
    
        # a socket to connect to APNS over SSL
        _sock = socket.socket()
        _ssl = ssl.wrap_socket(_sock, certfile=pem_file,
                                      server_side=False,
                                      cert_reqs=ssl.CERT_REQUIRED,
                                      ssl_version=ssl.PROTOCOL_TLSv1,
                                      ca_certs=ca_certs)
        _ssl.connect(apns_address)
    
        # a notification packet
        payload = json.dumps(PAYLOAD)
        token = binascii.unhexlify(TOKEN)
        fmt = '!cH32sH{0:d}s'.format(len(payload))
        cmd = '\x00'
        message = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
    
        _ssl.write(message)
        _ssl.close()
    
        return self.response_result(PAYLOAD)

    …ausgeführt, ohne Fehler.

  3. 0

    Auch Experimentieren, habe ich herausgefunden, dass SSL-Fehler auf der App Engine in der Regel gehen Weg, wenn ich das integrierte 3rd-party-ssl-lib:

    libraries:
    - name: ssl
      version: latest

    oder:

    libraries:
    - name: ssl
      version: "2.7"
    • Gute Beratung, ich habe mit dem Namen: ssl-version: „2.7“ – notation, die in meiner app.ymal und diese Prozedur liest die import-ssl ohne Fehler.
    • und das handshake-Fehler?
    • …weiter, oder ersetzen Sie mit „SSLError: [Errno 0] _ssl.c:343: Fehler:00000000:lib(0):func(0):reason(0)“ das problem, Das ich habe erscheint zentriert auf Zertifikate.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.