公钥验证

通过公钥验证进行检查

与其他应用商店一样,您必须将Catappult的公钥添加到后端以验证交易。

您可以在此处了解:如何获得我的公钥。

添加 Catappult 公钥

本节将合并一些建议,以便在后端服务器上添加新的公钥,同时能够处理来自其他服务提供商的消费。

检查 purchaseToken 字段

您可以解析后端收到的消费记录,并在您的 purchaseToken 包含前缀 'catappult.inapp.purchase' 时使用我们的公钥。

请参阅以下的代码片段了解执行的具体方法:

import base64
import json

import rsa
from rsa import PublicKey


class PublicKeyValidator:
    def __init__(self):
        pass

    def parse_public_key(self, _public_key: str) -> PublicKey:
        pem_key = self.build_pem(_public_key)
        return rsa.PublicKey.load_pkcs1_openssl_pem(pem_key.encode())

    def build_pem(self, _public_key: str) -> str:
        return '\n'.join((
            '-----BEGIN PUBLIC KEY-----',
            '\n'.join(_public_key[i:i+64] for i in range(0, len(_public_key), 64)),
            '-----END PUBLIC KEY-----'
        ))

    def validate_purchase(self, _public_key: PublicKey,
                          _receipt: str, _signature: str) -> bool:
        try:
            decoded_signature = base64.standard_b64decode(_signature)
            if rsa.verify(_receipt.encode(), decoded_signature, _public_key):
                return True
        except (rsa.VerificationError, TypeError, ValueError, BaseException):
            return False


if __name__ == "__main__":
    public_key_validator = PublicKeyValidator()
    cat_public_key = "YOUR_CATAPPULT_PUBLIC_KEY"

    incoming_receipt = """USER_PURCHASE_RECEIPT"""
    incoming_signature = "USER_PURCHASE_SIGNATURE"

    purchase_token: str = json.loads(incoming_receipt)["purchaseToken"]
    if purchase_token.startswith("catappult.inapp.purchase"):
        print("Using Catappult Public-key")
        public_key = public_key_validator.parse_public_key(cat_public_key)
        is_success = public_key_validator.validate_purchase(
            public_key, incoming_receipt, incoming_signature)
        print("Purchase status: ", is_success)
    else:
        # Reject or use other provider

创建一个包含所有公钥的列表

一个包含所有公钥(用于Catappult、谷歌商店 (Google Play) 等)的列表可以用于验证之后的消费记录。

请参阅以下的代码片段了解执行的具体方法:

import base64
import json

import rsa
from rsa import PublicKey


class PublicKeyValidator:
    def __init__(self):
        pass

    def parse_public_key(self, _public_key: str) -> PublicKey:
        pem_key = self.build_pem(_public_key)
        return rsa.PublicKey.load_pkcs1_openssl_pem(pem_key.encode())

    def build_pem(self, _public_key: str) -> str:
        return '\n'.join((
            '-----BEGIN PUBLIC KEY-----',
            '\n'.join(_public_key[i:i+64] for i in range(0, len(_public_key), 64)),
            '-----END PUBLIC KEY-----'
        ))

    def validate_purchase(self, _public_key: PublicKey,
                          _receipt: str, _signature: str) -> bool:
        try:
            decoded_signature = base64.standard_b64decode(_signature)
            if rsa.verify(_receipt.encode(), decoded_signature, _public_key):
                return True
        except (rsa.VerificationError, TypeError, ValueError, BaseException):
            return False


if __name__ == "__main__":
    public_key_validator = PublicKeyValidator()
    public_keys = ["YOUR_CATAPPULT_PUBLIC_KEY", "YOUR_GOOGLE_PUBLIC_KEY"]

    incoming_receipt = """USER_PURCHASE_RECEIPT"""
    incoming_signature = "USER_PURCHASE_SIGNATURE"

    purchase_token: str = json.loads(incoming_receipt)["purchaseToken"]
    for public_key in public_keys:
        print("Checking purchase with '{}'".format(public_key))
        public_key = public_key_validator.parse_public_key(public_key)
        is_success = public_key_validator.validate_purchase(
            public_key, incoming_receipt, incoming_signature)
        if is_success:
            print("Purchase successfully validated")