我一直在尝试使用新的iOS Game Center GKPlayer方法generateIdentityVerificationSignatureWithCompletionHandler,因此我们可以安全地依赖Game Center凭据进行身份验证。我们使用Node.js作为后端服务器,我一直在尝试验证签名,但无济于事。
以下是我所拥有的服务器端代码 - 如果有人可以查看缺少的内容,那将不胜感激。这个问题在这里得到了一些回答:How to authenticate the GKLocalPlayer on my 'third party server'?,但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);
}
});
});
我发现在node.js中使用crypto模块的一件事是它似乎想要PEM格式的证书,我相信从Apple检索的格式是DER。在我弄清楚如何将DER文件转换为PEM之前,我暂时使用
转换它openssl x509 -in gc-sb.cer -inform der -outform pem -out gc-sb.pem
对我来说最重要的是能够首先验证签名。转换证书并对签名机构进行验证将在稍后进行:)
编辑:我已经弄明白了 - 我正在对playerId,bundleId,timestamp和salt进行哈希处理,然后使用哈希值作为验证信息。我需要将这些信息放入验证程序中,以便在没有SHA-1哈希的情况下进行验证(因为验证程序将负责处理它)。我已将上面的代码修改为“使其正常工作”。希望这可以帮助遇到这种情况的任何人。
答案 0 :(得分:1)
以下是使用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);
}
});
答案 1 :(得分:1)
所以今天我们注意到需要SHA256来验证用户,SHA1失败。
答案 2 :(得分:1)