47 lines
1.8 KiB
C#
47 lines
1.8 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine.Purchasing;
|
||
|
using System.Security.Cryptography;
|
||
|
|
||
|
namespace UnityEngine.Purchasing.Security
|
||
|
{
|
||
|
internal class GooglePlayValidator
|
||
|
{
|
||
|
private RSAKey key;
|
||
|
public GooglePlayValidator(byte[] rsaKey)
|
||
|
{
|
||
|
key = new RSAKey(rsaKey);
|
||
|
}
|
||
|
|
||
|
public GooglePlayReceipt Validate(string receipt, string signature)
|
||
|
{
|
||
|
var rawReceipt = System.Text.Encoding.UTF8.GetBytes(receipt); // "{\"orderId\":\"G...
|
||
|
var rawSignature = System.Convert.FromBase64String(signature);
|
||
|
|
||
|
if (!key.VerifySha1(rawReceipt, rawSignature))
|
||
|
{
|
||
|
throw new InvalidSignatureException();
|
||
|
}
|
||
|
|
||
|
var dic = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);
|
||
|
object orderID, packageName, productId, purchaseToken, purchaseTime, purchaseState;
|
||
|
|
||
|
dic.TryGetValue("orderId", out orderID);
|
||
|
dic.TryGetValue("packageName", out packageName);
|
||
|
dic.TryGetValue("productId", out productId);
|
||
|
dic.TryGetValue("purchaseToken", out purchaseToken);
|
||
|
dic.TryGetValue("purchaseTime", out purchaseTime);
|
||
|
dic.TryGetValue("purchaseState", out purchaseState);
|
||
|
|
||
|
// Google specifies times in milliseconds since 1970.
|
||
|
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||
|
// NOTE: to safely handle null values for these fields, using Convert.ToDouble & ToInt32 in place of casts
|
||
|
var time = epoch.AddMilliseconds(Convert.ToDouble(purchaseTime));
|
||
|
var state = (GooglePurchaseState)Convert.ToInt32(purchaseState);
|
||
|
|
||
|
return new GooglePlayReceipt((string)productId, (string)orderID, (string)packageName,
|
||
|
(string)purchaseToken, time, state);
|
||
|
}
|
||
|
}
|
||
|
}
|