Android应用内结算验证Dot Net中的收据(C#)

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

Jon*_*ric 5

这是一个纯粹的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)


Mub*_*har 3

我找到了解决方案,要实现这一点,您首先必须转换公钥格式,因为点网使用不同的密钥作为输入。

我不知道其他方法,但我们可以使用 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)

我希望它对每个人都有效,就像对我一样。谢谢

归功于Code Project Artical