Mub*_*har 9 .net android cryptography in-app-purchase
我有一个Android应用程序,它提供应用程序内的计费,我们有我们的应用程序服务器,Android应用程序连接到用户提供服务,在应用内购买我们要将收据推送到服务器进行验证过程.
现在的问题是我不知道如何在点网(C#)中转换Security.java文件,因为我们的服务器是用点网写的
注意:此文件附带android应用程序内计费相同的应用程序,它提供了消息签名功能,我只需要在dot net中等效.
有关此问题的更多详细信息,请访问 http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/66bb5683-fde6-47ca-92d7-de255cc8655a
这是一个纯粹的C#实现,来自在.Net上检查Google Play签名.
创建一个控制台应用程序项目,将公钥转换为RSACryptoServiceProvider期望的XML格式.将PEMKeyLoader.cs添加到控制台应用程序项目中.
using PublicKeyConvert;
using System.Security.Cryptography;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
RSACryptoServiceProvider provider = PEMKeyLoader.CryptoServiceProviderFromPublicKeyInfo(MY_BASE64_PUBLIC_KEY);
System.Console.WriteLine(provider.ToXmlString(false));
}
const string MY_BASE64_PUBLIC_KEY = "Paste your base64 Google public key here.";
}
}
Run Code Online (Sandbox Code Playgroud)
运行该控制台应用程序将输出(到控制台)RSACryptoServiceProvider期望的XML格式.
现在您已拥有XML格式的公钥,您可以使用它来验证签名:
public static bool Verify(string message, string base64Signature, string xmlPublicKey)
{
// Create the provider and load the KEY
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPublicKey);
// The signature is supposed to be encoded in base64 and the SHA1 checksum
// of the message is computed against the UTF-8 representation of the message
byte[] signature = System.Convert.FromBase64String(base64Signature);
SHA1Managed sha = new SHA1Managed();
byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
return provider.VerifyData(data, sha, signature);
}
Run Code Online (Sandbox Code Playgroud)
我找到了解决方案,要实现这一点,您首先必须转换公钥格式,因为点网使用不同的密钥作为输入。
我不知道其他方法,但我们可以使用 java 代码获取点网格式密钥,您只需运行一次即可生成点网友好的 RSA 公钥。(仅当给定的公众不会快速变化时才建议这样做,例如在 Android 市场应用内计费的情况下)
以下Java代码对我有用
public static DotNetRSA GenerateDotNetKey(String base64PubKey)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
/*
* String base64PubKey -
* Is a Key retrieved from Google Checkout Merchant Account
*/
BASE64Decoder decoder = new BASE64Decoder();
byte[] publicKeyBytes = decoder.decodeBuffer(base64PubKey);
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(publicKeySpec);
byte[] modulusBytes = publicKey.getModulus().toByteArray();
byte[] exponentBytes = publicKey.getPublicExponent().toByteArray();
modulusBytes = stripLeadingZeros(modulusBytes);
BASE64Encoder encoder = new BASE64Encoder();
String modulusB64 = encoder.encode(modulusBytes);
String exponentB64 = encoder.encode(exponentBytes);
return new DotNetRSA(modulusB64, exponentB64);
}
private static byte[] stripLeadingZeros(byte[] a) {
int lastZero = -1;
for (int i = 0; i < a.length; i++) {
if (a[i] == 0) {
lastZero = i;
}
else {
break;
}
}
lastZero++;
byte[] result = new byte[a.length - lastZero];
System.arraycopy(a, lastZero, result, 0, result.length);
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在要验证数字签名,您可以在 dot net 程序(c#)中使用以下代码,前提是 GCHO_PUB_KEY_EXP 是您的指数,GCHO_PUB_KEY_MOD 是由上述 Java 代码提取的模数
public static bool VerifyDataSingature(string data, string sign)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
RSAParameters rsaKeyInfo = new RSAParameters()
{
Exponent = Convert.FromBase64String(GCHO_PUB_KEY_EXP),
Modulus = Convert.FromBase64String(GCHO_PUB_KEY_MOD)
};
rsa.ImportParameters(rsaKeyInfo);
return rsa.VerifyData(Encoding.ASCII.GetBytes(data),
"SHA1",
Convert.FromBase64String(sign));
}
}
Run Code Online (Sandbox Code Playgroud)
我希望它对每个人都有效,就像对我一样。谢谢
| 归档时间: |
|
| 查看次数: |
8068 次 |
| 最近记录: |