google Play iap 服务端验证(java)

最近公司要做海外版,需要接入google play.踩了不少坑,特作此文
20180809更新,增加导包,参数示例数据

验证方法1 rsa签名验证

请参考这篇

验证方法2 请求google api验证

需要在google developer console申请service account,具体参考这篇

我的做法 我比较diao,两种都上了(手动滑稽)

其实是因为之前我认为publicKey在客户端也存在,可能有风险,真正明白后才知道rsa的公匙本来就是可以可以公开的,私匙是有google有,肯定是安全的,但是代码已经上线了,也浪费不了多少资源,算是双重保险吧

放码过来

maven依赖


            com.google.apis
            google-api-services-androidpublisher
            v2-rev44-1.22.0
        

充值接口,在这里进行充值操作

public Map vertifyOrder(
            @RequestParam("purchaseData") String purchaseData,
            @RequestParam("signature") String signature,
            @RequestParam("type") int type) {

拦截器,通过后的请求才会调用充值接口.key.p12文件是在classpath下

import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Collections;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.SecurityUtils;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import com.google.api.services.androidpublisher.model.ProductPurchase;
/**
 * @author weilong.wang Created on 2017/12/8
 */
@Aspect
@Component
public class GoogleSignInterceptor {
    private static final Logger logger = LoggerManage.getLogger();
    private static final String SERVICE_ACCOUNT_EMAIL = "{googlePlay.serviceAccountEmail}";
    private static final String PUBLIC_KEY = "{googlePlay.publicKey}";
    private static final String P12_Key = "/key.p12";

    @Around("execution(* xxx.xxx.xxx.vertifyOrder (..))")
    public Object preHandle(ProceedingJoinPoint proceedingJoinPoint) {
        Object[] args = proceedingJoinPoint.getArgs();
        // 获取参数
        String signature = null;
        String purchaseData = null;
        try {
            purchaseData = String.valueOf(args[0]);
            signature = String.valueOf(args[1]);
        } catch (NullPointerException e) {
            logger.error("参数为空");
        }

        // 签名校验
        String publicKey = ConfigManager.getProperty(PUBLIC_KEY);
        try {
            boolean isVertify = docheck(purchaseData, signature, publicKey);
            if (isVertify == false) {
                logger.error("签名校验失败publicKey:" + publicKey);
            }
        } catch (Exception e) {
            logger.error("签名校验失败", e);
        }
        // 调用google api二次校验
        com.alibaba.fastjson.JSONObject jsonObject;
        try {
            jsonObject = JSON.parseObject(purchaseData);
        } catch (JSONException e) {
            logger.error("purchaseData解析失败", e);
        }
        String productId = jsonObject.getString("productId");
        String packageName = jsonObject.getString("packageName");
        String purchaseToken = jsonObject.getString("purchaseToken");
        int purchaseState = jsonObject.getIntValue("purchaseState");
        if (purchaseState != 0) {
            logger.error("订单未支付!");
        }
        
        try {

            HttpTransport transport = GoogleNetHttpTransport
                    .newTrustedTransport();
            PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(
                    SecurityUtils.getPkcs12KeyStore(),
                    this.getClass().getResourceAsStream(P12_Key), "notasecret",
                    "privatekey", "notasecret");
            GoogleCredential credential = new GoogleCredential.Builder()
                    .setTransport(transport)
                    .setJsonFactory(JacksonFactory.getDefaultInstance())
                    .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                    .setServiceAccountScopes(Collections
                            .singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
                    .setServiceAccountPrivateKey(privateKey).build();
            AndroidPublisher publisher = new AndroidPublisher.Builder(transport,
                    JacksonFactory.getDefaultInstance(), credential).build();
            AndroidPublisher.Purchases.Products products = publisher.purchases()
                    .products();
            AndroidPublisher.Purchases.Products.Get product = products
                    .get(packageName, productId, purchaseToken);

            ProductPurchase purchase = product.execute();
            if (purchase.getPurchaseState() != 0) {
                logger.error("订单未支付!");
            }
        } catch (Exception e) {
            logger.error("订单验证失败! ", e);
        }

        try {
            return proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            logger.error("系统错误", throwable);

        }
    }

    private boolean docheck(String content, String sign, String publicKey)
            throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] encodedKey = Base64.getDecoder().decode(publicKey);
        PublicKey pubKey = keyFactory
                .generatePublic(new X509EncodedKeySpec(encodedKey));
        Signature signature = Signature.getInstance("SHA1WithRSA");
        signature.initVerify(pubKey);
        signature.update(content.getBytes("utf-8"));
        return signature.verify(Base64.getDecoder().decode(sign));
    }
}


前端传递的参数,仅供参考,隐私信息已去除

purchaseData={"orderId":"GPA.3330-4532-0035-01959","packageName":"{packageName}","productId":"{productName}","purchaseTime":1533737586295,"purchaseState":0,"developerPayload":"9c97bb8c-1320-4088-a9c8-6ead08325655{productName}","purchaseToken":"hcgakhnoeoiikhjicdlobfkm.AO-J1OykrKdrP6OFvIvNN3P_ZPOP8IlJSqIO95fiDYhWpB8hN6_PX23XtsEjNg8y5-pCM5AjCp8lZ_daGTQOS9HGS20xA7ev3DEqwl5_HQDnvIGTlrr_divZaA8F6zYTkF3lngn2n11j5DswMyqq84Cz6v2JlKwGWg"}&signature=fP3liv/tbrw0PUgQA/iCymOL1l56wBY8bLgqK58ktcIHGgai166ijpg9jbx3QvJ9ljgmwJca/7N/n6jzzADTy49rtpY2sNvaZDrHcwVLXXfRT9tPgMi2NgTGfRGgNw7lwXH9TkewU7rSJmeDznnuEpf8cfO24FgoUi61XZEPFrz8G83O94nQvNUgIirXQZneKmRGYWrZcomuaHmAVP3CtEchvO0AjlhDsbvZIePfkfPOAgR5PWNgwo0YpNS0TZzSErdPCDgJMxRyztisuqQnExSXnjnGtUQDSk4Ohdu4sIoeLDez8gC30yJ+g8dAtuwLw5L+yxXsEYnX7ALZk950Xg==&type=1

你可能感兴趣的:(google Play iap 服务端验证(java))