如何从第三方node.js服务器验证Game Center用户

Sim*_*ang 5 authentication ssl-certificate node.js ios game-center

我一直在尝试使用新的iOS Game Center GKPlayer方法,generateIdentityVerificationSignatureWithCompletionHandler,这样我们就可以安全地依赖Game Center凭据进行身份验证.我们使用Node.js作为后端服务器,我一直在尝试验证签名,但无济于事.

以下是我所拥有的服务器端代码 - 如果有人可以查看缺少的内容,那将不胜感激.问题在这里有所回答:如何在我的'第三方服务器'上验证GKLocalPlayer?,但Node.js没有专门解决.请注意,下面的代码不能确保具有签名权限的证书的有效性(尚未).

    //Client sends the payload below
    //json.playerId - UTF-8 string
    //json.bundleId - UTF-8 string
    //json.timestamp - Hex string
    //json.salt - base64 encoded
    //json.publicKeyURL - UTF-8 string
    //json.signature - base64 encoded
    var json = JSON.parse(req.body);
    console.log(JSON.stringify(json));
    //get the certificate
    getCertificate(json.publicKeyURL, function(cert){
        //read file from fs for now, since getCertificate returns cert in DER format
        fs = require('fs');
        fs.readFile('/gc-sb.pem', 'utf8', function (err,data) {
            if (err) {
                console.log(err);
            } else {
                console.log(data);
            var verifier = crypto.createVerify("sha1WithRSAEncryption");
            verifier.write(json.playerId, "utf8");
            verifier.write(json.bundleId, "utf8");
            verifier.write(json.hexTimestamp, "hex");
            verifier.write(json.salt, "base64");
            var isValid = verifier.verify(data, json.signature, "base64");

            console.log("isvalid: " + isValid);
            }
        });
    });
Run Code Online (Sandbox Code Playgroud)

我在node.js中使用crypto模块发现的一件事是它似乎想要PEM格式的证书,我相信从Apple检索的格式是DER.直到我弄清楚如何将DER文件转换为PEM,我才暂时使用它进行转换

openssl x509 -in gc-sb.cer -inform der -outform pem -out gc-sb.pem
Run Code Online (Sandbox Code Playgroud)

对我来说最重要的是能够首先验证签名.转换证书并将其与签名机构进行验证将在稍后进行:)

编辑:我已经弄明白了 - 我正在哈希播放playerId,bundleId,timestamp和salt,然后使用散列值作为信息进行验证.我需要将这些信息放入验证程序中,以便在没有SHA-1哈希的情况下进行验证(因为验证程序将负责处理它).我已将上面的代码修改为"使其正常工作".希望这可以帮助遇到这种情况的任何人.

xjo*_*oin 3

以下是如何使用 Nodejs 验证游戏中心身份。它还可以将 der 证书格式动态转换为 pem。

var crypto = require('crypto');
var request = require('request');
var ref = require('ref');

var token = require('./test.json');

request({url: token.publicKeyURL, encoding: null}, function (error, response, body) {
    if (!error && response.statusCode == 200) {

        var verifier = crypto.createVerify("sha1");
        verifier.update(token.playerId, "utf8");
        verifier.update(token.bundleId, "utf8");

        var buf = ref.alloc('uint64');
        ref.writeUInt64BE(buf, 0, token.timestamp.toString());

        verifier.update(buf);
        verifier.update(token.salt, 'base64');

        var pmd = '-----BEGIN CERTIFICATE-----';

        var base64 = body.toString('base64');
        var size = base64.length;

        for (var i = 0; i < size; i = i + 64) {
            var end = i + 64 < size ? i + 64 : size;
            pmd = pmd + '\n' + base64.substring(i, end);
        }

        pmd = pmd + '\n-----END CERTIFICATE-----';

        var valid = verifier.verify(pmd, token.signature, "base64");

        console.log(valid);

    }
});
Run Code Online (Sandbox Code Playgroud)