ios gamecenter 登录验证 java服务端实现

    业务上需要使用gamecenter进行登录,官方文档说的比较简单,也没有示例代码可以看。网上找一通也没发现有java的实现,所以只能根据文档自己敲代码了。
下面给出官方文档:
https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion

关键就在于下面这段:

后端验证步骤



客户端传到后端的参数有publicKeyURL、signature、timestamp、playerID、bundleID、salt。
我们需要访问publicKeyUrl,获得公钥。并通过公钥对客户端的数据进行校验,校验通过则合法。


关键是第6点,我们需要把这些参数的字节进行拼接(一开始我直接用字符串拼接,怎么也验证不了),salt需要先进行base64decode。由于java本身就是大端的,所以timestamp直接用就行了。

代码实现

拼接第6步代码如下,获得字节数组:

public static byte[] concatContent(String playerId, String bundleId, long timestamp, String salt)
            throws IOException {
        return Bytes.concat(playerId.getBytes(Charsets.UTF_8), bundleId.getBytes(Charsets.UTF_8), toBigEndian(timestamp) ,
                Base64.decodeBase64(salt));
    }

private static byte[] toBigEndian(long value){
        byte[] buffer = new byte[8];
        for (int i = 0; i < 8; i++) {
            buffer[7 - i] = (byte)(value & 0xff);
            value = value >> 8;
        }
        return buffer;
    }

验证代码如下:

/**
     *
     * @param publicKeyInput 访问publicKeyURL获得的字节流
     * @param sign 客户端穿过来的sign,需要先进行base64decode
     * @param original concatContent方法获得的字节数组
     * @return
     */
public static boolean verifySign(InputStream publicKeyInputstream, byte[] sign, byte[] content) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("x.509");
            X509Certificate cer = (X509Certificate)cf.generateCertificate(publicKeyInputstream);
            cer.checkValidity();
            PublicKey publicKey = cer.getPublicKey();
            Signature signature = Signature.getInstance(cer.getSigAlgName());
            signature .initVerify(publicKey);
            signature .update(content);
            return signature.verify(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

main方法测试:

public static void main(String args[]){
    String playerId = "xxxx";
    String publicKeyUrl = "https://static.gc.apple.com/public-key/gc-prod-3.cer";
    String bundleId = "com.xxx.xxx.game";
    long timestamp = 1231231232L;
    String salt = "d0xRFw==";
    String sign = "augUgRE/INZLLARzyFe3/HoB9fA5IrxdmFUsq";
    byte[] data = concatSignature(playerId , bundleId, timestamp, salt);
    byte[] signBytes = Base64.decodeBase64(sign);
    InputStream publicKeyInputStream = HttpHelper.get(publicKeyUrl);
    boolean result = verifySign(publicKeyInputStream , signBytes, data);
    System.out.println(result);
}

你可能感兴趣的:(ios gamecenter 登录验证 java服务端实现)