Ошибка 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()