2011-03-26 19 views
14

पर पायथन में एंड्रॉइड इन-ऐप खरीद संदेश पर हस्ताक्षर की पुष्टि करना एंड्रॉइड डेवलपर्स साइट पर नमूना एप्लिकेशन जावा कोड का उपयोग कर खरीद जेसन को मान्य करता है। क्या किसी के पास कोई भाग्य है कि पाइथन में खरीद को कैसे वैध किया जाए। विशेष रूप से जीएई में?Google ऐप इंजन

एंड्रॉइड इन-ऐप बिलिंग example program से प्रासंगिक अंश निम्नलिखित हैं। PyCrypto का उपयोग करके इसे पायथन में परिवर्तित करने की आवश्यकता होगी जिसे Google द्वारा पूरी तरह से पाइथन के रूप में फिर से लिखा गया था और ऐप इंजन पर उपलब्ध एकमात्र सुरक्षा lib है। उम्मीद है कि नीचे दिए गए अंशों का उपयोग करके Google मेरे साथ अच्छा है।

private static final String KEY_FACTORY_ALGORITHM = "RSA"; 
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; 
String base64EncodedPublicKey = "your public key here"; 

PublicKey key = Security.generatePublicKey(base64EncodedPublicKey); 
verified = Security.verify(key, signedData, signature); 

public static PublicKey generatePublicKey(String encodedPublicKey) { 
    try { 
     byte[] decodedKey = Base64.decode(encodedPublicKey); 
     KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); 
     return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); 
    } catch ... 
    } 
} 
public static boolean verify(PublicKey publicKey, String signedData, String signature) { 
    if (Consts.DEBUG) { 
     Log.i(TAG, "signature: " + signature); 
    } 
    Signature sig; 
    try { 
     sig = Signature.getInstance(SIGNATURE_ALGORITHM); 
     sig.initVerify(publicKey); 
     sig.update(signedData.getBytes()); 
     if (!sig.verify(Base64.decode(signature))) { 
      Log.e(TAG, "Signature verification failed."); 
      return false; 
     } 
     return true; 
    } catch ... 
    } 
    return false; 
} 
+0

मैं एक के रूप में इस पोस्ट करने के लिए नहीं जा रहा हूँ जवाब क्योंकि मैं यह नहीं बता सकता कि क्या आप इसकी तलाश में हैं, लेकिन इसे [लिंक - Google Code] (http://code.google.com/appengine/articles/rpc.html) आज़माएं, यह दिखाता है कि कैसे लिखना है जीएई ऐप जो जेएसओएन के साथ जवाब देगा, जिसे आप अपना सत्यापन प्रदान करने के लिए संशोधित कर सकते हैं, मुझे लगता है कि – Timbermar

उत्तर

15

यहां बताया गया है मैं यह किया:

from Crypto.Hash import SHA 
from Crypto.PublicKey import RSA 
from Crypto.Signature import PKCS1_v1_5 
from base64 import b64decode 

def chunks(s, n): 
    for start in range(0, len(s), n): 
     yield s[start:start+n] 

def pem_format(key): 
    return '\n'.join([ 
     '-----BEGIN PUBLIC KEY-----', 
     '\n'.join(chunks(key, 64)), 
     '-----END PUBLIC KEY-----' 
    ]) 

def validate_purchase(publicKey, signedData, signature): 
    key = RSA.importKey(pem_format(publicKey)) 
    verifier = PKCS1_v1_5.new(key) 
    data = SHA.new(signedData) 
    sig = b64decode(signature) 
    return verifier.verify(data, sig) 

इसमें यह माना जाता publicKey अपने बेस 64 Google Play एक लाइन पर स्टोर कुंजी के रूप में आप इसे डेवलपर कंसोल से प्राप्त इनकोडिंग है।

लोग हैं, जो बल्कि m2crypto का उपयोग के लिए, validate_purchase() करने के लिए बदल जाएगा:

from M2Crypto import RSA, BIO, EVP 
from base64 import b64decode 

# pem_format() as above 

def validate_purchase(publicKey, signedData, signature): 
    bio = BIO.MemoryBuffer(pem_format(publicKey)) 
    rsa = RSA.load_pub_key_bio(bio) 
    key = EVP.PKey() 
    key.assign_rsa(rsa) 
    key.verify_init() 
    key.verify_update(signedData) 
    return key.verify_final(b64decode(signature)) == 1 
+0

मुझे इसे कार्य करने के लिए 'validate_purchase (publicKey, signData, हस्ताक्षर) 'फ़ंक्शन में निम्न पंक्ति जोड़नी है: 'हस्ताक्षरित डेटा = हस्ताक्षरित डेटा.एकोड (" utf8 ")' – Saqib

+0

धन्यवाद, आपने मेरा दिन बनाया! आप Google लाइसेंस को एक वैध सार्वजनिक कुंजी में भी बदल सकते हैं जैसे: 'openssl enc -base64 -d -in publickey.base64 -A | openssl आरएसए -इनफॉर्म डीईआर-पबिन> publickey.pem' – Moritz

7

मैं अंत में पता लगा है कि अपने बेस 64 इनकोडिंग Google Play से सार्वजनिक कुंजी है एक 509 subjectPublicKeyInfo डीईआर अनुक्रम, और कहा कि हस्ताक्षर योजना आरएसएसएसएसएसए-पीकेसीएस 1-वी 1_5 है और आरएसएसएसएएस-पीएसएस नहीं है। कि हम 2016 में हैं

import base64 
from Crypto.Hash import SHA 
from Crypto.PublicKey import RSA 
from Crypto.Signature import PKCS1_v1_5 

# Your base64 encoded public key from Google Play. 
_PUBLIC_KEY_BASE64 = "YOUR_BASE64_PUBLIC_KEY_HERE" 
# Key from Google Play is a X.509 subjectPublicKeyInfo DER SEQUENCE. 
_PUBLIC_KEY = RSA.importKey(base64.standard_b64decode(_PUBLIC_KEY_BASE64)) 

def verify(signed_data, signature_base64): 
    """Returns whether the given data was signed with the private key.""" 

    h = SHA.new() 
    h.update(signed_data) 
    # Scheme is RSASSA-PKCS1-v1_5. 
    verifier = PKCS1_v1_5.new(_PUBLIC_KEY) 
    # The signature is base64 encoded. 
    signature = base64.standard_b64decode(signature_base64) 
    return verifier.verify(h, signature) 
+0

यह उत्तर कुंजी प्रारूप को मोंग करने से बचाता है और ठीक काम करता है। –

1

अब, यहाँ कैसे cryptography साथ यह करना है:: आप PyCrypto स्थापित है, तो यह वास्तव में काफी आसान है

import base64 
import binascii 

from cryptography.exceptions import InvalidSignature 
from cryptography.hazmat.backends import default_backend 
from cryptography.hazmat.primitives import hashes, serialization 
from cryptography.hazmat.primitives.asymmetric import padding 


class RSAwithSHA1: 
    def __init__(self, public_key): 
     # the public key google gives you is in DER encoding 
     # let cryptography handle it for you 
     self.public_key = serialization.load_der_public_key(
      base64.b64decode(public_key), backend=default_backend() 
     ) 

    def verify(self, data, signature): 
     """ 
     :param str data: purchase data 
     :param str signature: data signature 
     :return: True signature verification passes or False otherwise 
     """ 
     # note the signature is base64 encoded 
     signature = base64.b64decode(signature.encode()) 
     # as per https://developer.android.com/google/play/billing/billing_reference.html 
     # the signature uses "the RSASSA-PKCS1-v1_5 scheme" 
     verifier = self.public_key.verifier(
      signature, padding.PKCS1v15(), hashes.SHA1(), 
     ) 
     verifier.update(data.encode()) 
     try: 
      verifier.verify() 
     except InvalidSignature: 
      return False 
     else: 
      return True