C# 如何在第三方服务器.net core上验证GKLocalPlayer

C# 如何在第三方服务器.net core上验证GKLocalPlayer,c#,asp.net-core,game-center,C#,Asp.net Core,Game Center,我有以下用于验证GKLocalPlayer的INF代码: var cert = await GetCertificate(gameCenter.PublicKeyURL); if (cert.Verify()) { var rsa = cert.GetRSAPublicKey(); if (rsa != null) { var sha256 = new SHA256Managed(); var sig = ConcatSignature(g

我有以下用于验证GKLocalPlayer的INF代码:

var cert = await GetCertificate(gameCenter.PublicKeyURL);
if (cert.Verify())
{
    var rsa = cert.GetRSAPublicKey();
    if (rsa != null)
    {
        var sha256 = new SHA256Managed();
        var sig = ConcatSignature(gameCenter.PlayerID, gameCenter.BundleID, gameCenter.TimeStamp, gameCenter.Salt);

        var hash = sha256.ComputeHash(sig);
        if (rsa.VerifyHash(hash, Convert.FromBase64String(gameCenter.Signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
        {
            return true;
        }
        return false;
    }
}

private async Task<X509Certificate2> GetCertificate(string url)
{
    var client = new HttpClient();
    var response = await client.GetAsync(url);
    var rawData = await response.Content.ReadAsByteArrayAsync();
    return new X509Certificate2(rawData);
}

private byte[] ConcatSignature(string playerId, string bundleId, string timestamp, string salt)
{
    var b = Convert.FromBase64String(salt);

    var data = new List<byte>();
    data.AddRange(Encoding.UTF8.GetBytes(playerId));
    data.AddRange(Encoding.UTF8.GetBytes(bundleId));
    data.AddRange(ToBigEndian(Convert.ToUInt64(timestamp)));
    data.AddRange(Convert.FromBase64String(salt));
    return data.ToArray();
}

private static byte[] ToBigEndian(ulong value)
{
    var buffer = new byte[8];
    for (int i = 0; i < 8; i++)
    {
        buffer[7 - i] = unchecked((byte)(value & 0xff));
        value = value >> 8;
    }
    return buffer;
}
var cert=wait-GetCertificate(gameCenter.PublicKeyURL);
如果(证书验证())
{
var rsa=cert.GetRSAPublicKey();
if(rsa!=null)
{
var sha256=新的SHA256Managed();
var sig=ConcatSignature(gameCenter.PlayerID、gameCenter.BundleID、gameCenter.TimeStamp、gameCenter.Salt);
var hash=sha256.ComputeHash(sig);
if(rsa.VerifyHash(hash,Convert.FromBase64String(gameCenter.Signature),HashAlgorithmName.SHA256,rsasignatureAdding.Pkcs1))
{
返回true;
}
返回false;
}
}
专用异步任务GetCertificate(字符串url)
{
var client=新的HttpClient();
var response=wait client.GetAsync(url);
var rawData=await response.Content.ReadAsByteArrayAsync();
返回新的X509Certificate2(原始数据);
}
私有字节[]ConcatSignature(字符串playerId、字符串bundleId、字符串时间戳、字符串salt)
{
var b=转换.FromBase64String(salt);
var data=新列表();
data.AddRange(Encoding.UTF8.GetBytes(playerId));
data.AddRange(Encoding.UTF8.GetBytes(bundleId));
data.AddRange(ToBigEndian(Convert.ToUInt64(timestamp));
data.AddRange(Convert.FromBase64String(salt));
返回data.ToArray();
}
专用静态字节[]ToBigEndian(ulong值)
{
var buffer=新字节[8];
对于(int i=0;i<8;i++)
{
缓冲区[7-i]=未检查((字节)(值&0xff));
值=值>>8;
}
返回缓冲区;
}
但当我试图验证GameCenter的准确性时,它总是返回false。我浏览了所有的评论,但我找不到任何专为.net核心和GKLocalPlayer验证发布的内容。

您的代码对我有用。 注意:如果不在设备上测试它,它将失败(因为数据是时间敏感的)