我正在尝试使用 .NET 的 Google Client API 库的 Google.Apis.PlayIntegrity.v1 命名空间来解码完整性令牌,如 Play Integrity API 文档中所推荐。
但是,从库文档中不清楚如何做到这一点。似乎解码后的令牌有效负载应该从
DecodeIntegrityTokenResponse
对象返回,但我找不到任何返回此类型的方法。
我希望这种类型会从
DecodeIntegrityToken(DecodeIntegrityTokenRequest, String)
返回,但这个方法实际上返回另一个 DecodeIntegrityTokenRequest
,这根本没有帮助。
有人成功使用这个库来解码令牌吗?
参考文献:
尝试的代码:
String integrityToken = "...token...";
String serviceAccountEmail = "...service account email...";
var certificate = new X509Certificate2("...key.p12...", "...secret...");
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { PlayIntegrityService.Scope.Playintegrity }
}.FromCertificate(certificate));
// Create the service.
var service = new PlayIntegrityService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Play Integrity API Sample",
});
DecodeIntegrityTokenRequest request = new DecodeIntegrityTokenRequest();
request.IntegrityToken = integrityToken;
DecodeIntegrityTokenResponse response = service.V1.DecodeIntegrityToken(request, "...package name...");
错误 CS0029 无法将类型“Google.Apis.PlayIntegrity.v1.V1Resource.DecodeIntegrityTokenRequest”隐式转换为“Google.Apis.PlayIntegrity.v1.Data.DecodeIntegrityTokenResponse”
你应该依靠你的ide来告诉你这些对象是什么类型
你的代码说方法
DecodeIntegrityToken
应该返回一个DecodeIntegrityTokenResponse
。您是这样声明它而不是使用 var
并允许编译器为您解决它。
DecodeIntegrityTokenResponse response = service.V1.DecodeIntegrityToken(request, "...package name...");
你的问题是这个方法实际上返回一个
DecodeIntegrityTokenRequest
.
要获得
DecodeIntegrityTokenResponse
,您需要执行请求
var request = service.V1.DecodeIntegrityToken(requestBody, "...package name...");
var result = request.Execute();
完整的代码清理
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using Google.Apis.PlayIntegrity.v1;
using Google.Apis.PlayIntegrity.v1.Data;
using Google.Apis.Services;
Console.WriteLine("Hello, World!");
var integrityToken = "...token...";
var serviceAccountEmail = "...service account email...";
var pathToCert = "...key.p12...";
var certPassword = "...secret...";
var packageName = "...package name...";
var certificate = new X509Certificate2(pathToCert, certPassword);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { PlayIntegrityService.Scope.Playintegrity }
}.FromCertificate(certificate));
// Create the service.
var service = new PlayIntegrityService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Play Integrity API Sample",
});
var requestBody = new DecodeIntegrityTokenRequest
{
IntegrityToken = integrityToken
};
var request = service.V1.DecodeIntegrityToken(requestBody, packageName);
var result = request.Execute();
我已经编写了一个示例应用程序来离线使用他们自己的密钥在 C# 中解密和验证播放完整性。
官方文档没有C#代码示例。
示例应用程序包含 .net 框架和 dotnet 核心的代码。
克隆应用程序后,搜索 //TODO 并使用适当的值进行更新。
您可以通过以下方式在本地解码认证语句。 我正在使用 Jose.jwt 来简化这里的代码。
var decryptionKey = Convert.FromBase64String("<DECRYPTION KEY>");
var verificationKey = Convert.FromBase64String("<VERIFICATION KEY>");
var signedAttestationStatement = "<ATTESTATION STATEMENT>";
var ecDsa = ECDsa.Create();
ecDsa.ImportSubjectPublicKeyInfo(new ReadOnlySpan<byte>(verificationKey), out _);
var decrypted = Jose.JWT.Decode(signedAttestationStatement, decryptionKey);
var payload = Jose.JWT.Decode(decrypted, ecDsa);