Ошибка SSL при внедрении Apple Push Notification

Я пытаюсь реализовать уведомление Apple Push с помощью python и django.

Я использую следующую библиотеку для ее реализации

http://leepa.github.com/django-iphone-push/

Вот мой код, который создает, который отправляет сообщение

from django.http import HttpResponse
from django.utils import simplejson
import json
from push.models import iPhone

def SendMessage(request,data):

        t = iPhone('XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ') # 64 digit token
        t.send_message("hi") # at this line i am getting ERROR
        return HttpResponse(data,mimetype='application/javascript')

settings.py

import os
PROJECT_ROOT = '/'

# Full path to the APN Certificate / Private Key .pem
IPHONE_SANDBOX_APN_PUSH_CERT = os.path.join(PROJECT_ROOT, "apns-dev-tubeteam.pem")
IPHONE_LIVE_APN_PUSH_CERT = os.path.join(PROJECT_ROOT, "apns-dev-tubeteam.pem")

# Set this to the hostname for the outgoing push server
IPHONE_SANDBOX_APN_HOST = 'gateway.sandbox.push.apple.com'
IPHONE_LIVE_APN_HOST = 'gateway.push.apple.com'

# Set this to the hostname for the feedback server
IPHONE_SANDBOX_FEEDBACK_HOST = 'feedback.sandbox.push.apple.com'
IPHONE_LIVE_FEEDBACK_HOST = 'feedback.push.apple.com'

Ошибка

[Errno 336265218] _ssl.c:337: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib

Кто-нибудь может рассказать мне, как избавиться от него.

Ответ 1

У меня была такая же проблема. Оказывается, это была простая ошибка - у меня была ошибка в IPHONE_SANDBOX_APN_PUSH_CERT, и python не смог найти мой сертификат. Как только я указал его в нужное место, он начал работать.

Обратите внимание, что сначала вы можете дважды проверить свой сертификат с помощью командной строки openssl, например:

openssl x509 -text -in cert.pem

Это даст вам текстовую информацию о вашем сертификате, его действительность и т.д.

Кроме того, дважды проверьте права доступа к файлу сертификата (процесс python должен иметь достаточные права для доступа к нему).

Ответ 2

Мое решение заключалось в том, что при создании моего файла .pem я устанавливаю пустой пароль и предполагаю, что это не означает пароль. поэтому сервер все еще ожидал использовать пароль. мне пришлось вручную удалить пароль.

вот немного, как руководство, если это кому-то помогает:

ПРИМЕЧАНИЕ. Вам необходимо следовать указаниям веб-сайта разработчика яблок, чтобы сначала создать сертификат  затем экспортируйте файл .p12,  путем экспорта встроенного закрытого ключа, который создается (в 'keychain access),  НЕ настоящий сертификат ------------------------------------ ------------------------------------ ДЛЯ РАЗВИТИЯ CERT: После получения файла p12 его необходимо преобразовать в формат PEM, выполнив эту команду с терминала: $ openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns_dev.p12 $ openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns_dev.p12

Если вы хотите удалить кодовую фразу, выполните следующие действия:  (ПРИМЕЧАНИЕ: использование "чистого пароля" при экспорте/конвертировании по-прежнему действительно устанавливает пароль,    поэтому вы должны выполнить следующее, если вы не хотите иметь пароль) $ openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem

Наконец, вам нужно объединить файлы ключей и сертификатов в файл apns-dev.pem, который мы будем использовать при подключении к APNS:

$cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

------------------------------------ ДЛЯ ПРОИЗВОДСТВЕННОГО КРЕСТА: После получения файла p12 его необходимо преобразовать в формат PEM, выполнив эту команду с терминала: $ openssl pkcs12 -clcerts -nokeys -out apns-prod-cert.pem -in apns_prod.p12 $ openssl pkcs12 -nocerts -out apns-prod-key.pem -in apns_prod.p12

Если вы хотите удалить кодовую фразу, выполните следующие действия:  (ПРИМЕЧАНИЕ: использование "чистого пароля" при экспорте/конвертировании по-прежнему действительно устанавливает пароль,    поэтому вы должны выполнить следующее, если вы не хотите иметь пароль) $ openssl rsa -in apns-prod-key.pem -out apns-prod-key-noenc.pem

Наконец, вам нужно объединить файлы ключей и сертификатов в файл apns-dev.pem, который мы будем использовать при подключении к APNS:

$cat apns-prod-cert.pem apns-prod-key-noenc.pem > apns-prod.pem

Ответ 3

Попробуйте использовать PyAPNs из
https://github.com/simonwhitaker/PyAPNs
или
pip install apns

И не забудьте получить сертификат APN и ключ от портала инициализации iOS, установить и преобразовать их в файлы .pem в следующем руководстве:
http://jainmarket.blogspot.com/2009/11/generate-apple-push-notification.html

Эта библиотека довольно проницаема.

Ответ 4

ИСПОЛЬЗУЙТЕ ЭТОТ КОД:

#!/usr/bin/python2.7

import socket
import ssl
import json
import struct
import argparse



APNS_HOST = ( 'gateway.sandbox.push.apple.com', 2195 )


class Payload:
    PAYLOAD = '{"aps":{${MESSAGE}${BADGE}${SOUND}}}'
    def __init__(self):
        pass

    def set_message(self, msg):
        if msg is None:
            self.PAYLOAD = self.PAYLOAD.replace('${MESSAGE}', '')
        else:
            self.PAYLOAD = self.PAYLOAD.replace('${MESSAGE}', '"alert":"%s",' % msg)

    def set_badge(self, num):
        if num is None:
            self.PAYLOAD = self.PAYLOAD.replace('${BADGE}', '')
        else:
            self.PAYLOAD = self.PAYLOAD.replace('${BADGE}', '"badge":%s,' % num)

    def set_sound(self, sound):
        if sound is None:
            self.PAYLOAD = self.PAYLOAD.replace('${SOUND}', '')
        else:
            self.PAYLOAD = self.PAYLOAD.replace('${SOUND}', '"sound":"%s",' % sound)

    def toString(self):
        return (self.PAYLOAD.replace('${MESSAGE}','').replace('${BADGE}','').replace('${SOUND}',''))

def connectAPNS(host, cert):
    ssl_sock = ssl.wrap_socket( socket.socket( socket.AF_INET, socket.SOCK_STREAM ), certfile = cert )
    ssl_sock.connect( APNS_HOST )
    return ssl_sock

def sendNotification(sslSock, device, message, badge, sound):
    payload = Payload()
    payload.set_message(message)
    payload.set_badge(badge)
    payload.set_sound(sound)
    payloadAsStr = payload.toString()

    format = '!BH32sH%ds' % len(payloadAsStr)
    binaryDeviceToken = device.replace(' ','').decode('hex')
    binaryNotification = struct.pack( format, 0, 32, binaryDeviceToken, len(payloadAsStr), payloadAsStr )

    print ("sending payload: ["+payloadAsStr+"] as binary to device: ["+device+"]")
    sslSock.write(binaryNotification)

def printUsageAndExit():
    print("msg2ios - Version 0.1\nmsg2IOS.py -d <device> -m <message> -s[plays sound] -b <badgeint>  -c <certBundlePath>")
    exit(1)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--device')
    parser.add_argument('-m', '--message')
    parser.add_argument('-s', '--sound')
    parser.add_argument('-b', '--badge')
    parser.add_argument('-c', '--cert')
    args = parser.parse_args()

    if (args.device is None) or ((args.message is None) and (args.sound is None) and (args.badge is None)) or (args.cert is None):
        printUsageAndExit()

    sslSock = connectAPNS(APNS_HOST, args.cert)
    sendNotification(sslSock, args.device, args.message, args.badge, args.sound)
    sslSock.close()