如何对iOS服务器到服务器通知请求进行身份验证?
如何验证App Store服务器到服务器通知的身份?
刚好做过App Store服务器通知的身份验证,来给你详细讲讲——Apple的方案和Play Store用JSON密钥的方式不太一样,核心是靠签名验证来确保请求确实来自官方,完全能解决你担心的安全风险问题。
核心:用Apple的签名证书验证通知合法性
Apple会用自己的私有密钥对每一条服务器通知进行签名,我们要做的就是用对应的公钥来验证这个签名的有效性,具体步骤拆解下:
- 先拿到验证所需的证书:你需要从Apple开发者后台获取用于验证通知签名的公钥证书(实际是通过证书链来确保可信度,要验证到Apple的根CA)。每个通知的HTTP请求头里会带三个关键字段:
Apple-Signature(签名值)、Apple-Signature-Version(签名版本,目前是v1)、Apple-Request-Id(请求唯一标识)。 - 验证签名的具体操作:
- 保留请求体的原始数据,绝对不能修改(哪怕是空格或换行,要和Apple发送的完全一致)。
- 把
Apple-Signature里的Base64编码签名值解码成二进制。 - 用验证过的Apple公钥,对请求体和签名做签名验证——确认这个签名确实是Apple用私有密钥生成的,没有被篡改。
- 同时要检查
Apple-Signature-Version是不是你支持的版本,避免处理无效的签名格式。
简单代码示例(伪代码)
给你写个Python风格的伪代码,大概是这个逻辑(实际实现要根据你的技术栈调整):
import jwt from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.backends import default_backend def validate_app_store_notification(request_body, apple_signature, signature_version): # 加载本地存储的Apple通知公钥证书(PEM格式,从开发者后台获取) with open("apple_notification_public_key.pem", "rb") as cert_file: cert_data = cert_file.read() cert = load_pem_x509_certificate(cert_data, default_backend()) public_key = cert.public_key() # 验证JWT签名(Apple的通知签名用的是ES256算法) try: decoded_payload = jwt.decode( apple_signature, public_key, algorithms=["ES256"], audience="你的服务器通知端点URL" # 要和你在App Store Connect里填的一致 ) # 可选但推荐:验证解码后的payload和原始请求体数据匹配 if decoded_payload.get("data") != request_body: return False return True except jwt.InvalidTokenError: # 签名无效、过期或不匹配的情况 return False
划重点:实际落地时一定要做证书链验证,确保你用的公钥确实是Apple根CA签发的,防止有人用伪造的证书来骗你。
额外的安全加固技巧
除了核心的签名验证,还可以加这些防护措施:
- 限制来源IP:Apple的服务器通知来自固定的IP范围,你可以在服务器防火墙或负载均衡器上配置白名单,只允许这些IP访问你的通知端点。
- 校验通知元数据:检查
notification_type和version字段,确保是你预期要处理的通知类型和版本,过滤掉无效或过时的请求。 - 强制HTTPS:这是App Store Connect的硬性要求,你的通知URL必须是HTTPS的,既能防止传输过程中数据被篡改,也能避免中间人攻击。
和Play Store的区别
对比Play Store用JSON密钥文件的验证方式,Apple的方案是公钥加密的签名验证——你不需要存储私有密钥,只需要验证Apple的签名有效性就行,这样就避免了私有密钥泄露的风险,安全性更有保障。
内容的提问来源于stack exchange,提问作者Anuja Joshi
相关产品推荐
相关产品推荐

