9
votes

Vérification de la facturation intégrée Android de la réception de DOT NET (C #)

J'ai une application Android qui fournit une facturation intégrée et nous avons notre serveur d'applications à laquelle l'application Android est connectée pour fournir des services à l'utilisateur, sur l'achat intégré, nous souhaitons appuyer sur la réception du serveur pour le processus de vérification.

Un problème maintenant est que je ne sais pas comment convertir Sécurité .java Fichier dans DOT NET (C #) Comme notre serveur est écrit dans DOT NET

Remarque: Ce fichier est livré avec Android In-App même application qui fournit des fonctions de signature des messages que j'ai juste besoin de leur équivalent dans DOT NET.

Plus de détails concernant ce problème est disponible à http: //social.msdn .microsoft.com / Forums / FR-US / NetFXBCl / Filetage / 66BB5683-FDE6-47CA-92D7-DE255CC8655A


0 commentaires

6 Réponses :


3
votes

J'ai trouvé la solution, pour vous réaliser, vous devez d'abord convertir le format de clé publique car DOT NET utilise un type de clé différente en tant qu'entrée.

Je ne connais pas les autres moyens, mais nous pouvons obtenir une clé de format net de point net à l'aide d'un code Java que vous devez exécuter une seule fois une fois pour générer la clé publique RSA conviviale DOT. (Ceci n'est recommandé que lorsque le public donné ne change pas rapidement, par exemple en cas de facturation intégrée de marché Android) p>

Suivre le code Java a fonctionné pour moi p>

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));
     }
}


5 commentaires

Merci pour la solution! C'est très utile.


Que se passe-t-il si Data contient des caractères non-ASCII? Depuis le nom de la poste, je suppose que data contiendra JSON qui est une chaîne et permet aux caractères non-ASCII.


@Ivan Akcheurov: Pas sûr, c'est certainement le premier brouillon du code. Donc, une telle erreur est attendue. Je ne me souviens pas de modifier le code moi-même.


Où est la définition de dotnetrsa ?


@nasch: Désolé Mate mais on dirait que le nom de classe constitue un nom de classe qui contient juste un module et un exposant.



1
votes

FYI pour la recherche de PEEPS, voici le fichier Java complet et la fonction de vb.net.

xxx

Il suffit d'ajouter à un nouveau projet Java et d'exécuter comme application Java avec un point de rupture (int i = 0;) Pour extraire vos clés, Code pas de la mienne, juste pure de moi, accessoires à l'auteur d'origine, lien au-dessus

et vb.net xxx


0 commentaires

3
votes

Pour tous les gens qui ont besoin de vérifier la signature ici sont une implémentation complète C # à l'aide de la DLL bouncycastle pour aider.

Si vous nourrissez la classe avec votre clé publique Google, vous pourrez vérifier les signatures, sans avoir besoin de Code Java. Aie du plaisir avec ça. GRTZ Martien P>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using System.Security.Cryptography;

namespace GoogleEncryptTest
{
    class GoogleSignatureVerify
{
    RSAParameters _rsaKeyInfo;

    public GoogleSignatureVerify(String GooglePublicKey)
    {
        RsaKeyParameters rsaParameters= (RsaKeyParameters) PublicKeyFactory.CreateKey(Convert.FromBase64String(GooglePublicKey)); 

        byte[] rsaExp   = rsaParameters.Exponent.ToByteArray();
        byte[] Modulus  = rsaParameters.Modulus.ToByteArray();

        // Microsoft RSAParameters modulo wants leading zero's removed so create new array with leading zero's removed
        int Pos = 0;
        for (int i=0; i<Modulus.Length; i++)
        {
            if (Modulus[i] == 0) 
            {
                Pos++;
            }
            else
            {
                break;
            }
        }
        byte[] rsaMod = new byte[Modulus.Length-Pos];
        Array.Copy(Modulus,Pos,rsaMod,0,Modulus.Length-Pos);

        // Fill the Microsoft parameters
        _rsaKeyInfo = new RSAParameters()
        {
            Exponent    = rsaExp,
            Modulus     = rsaMod
        };
    }

    public bool Verify(String Message,String Signature)
    {
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {      
            rsa.ImportParameters(_rsaKeyInfo);  
            return rsa.VerifyData(Encoding.ASCII.GetBytes(Message), "SHA1", Convert.FromBase64String(Signature));  
        }           
    }
}
}


2 commentaires

Fonctionne parfaitement merci!


Fonctionne juste "hors de la boîte"! Travaille également dans le noyau .NET. Les autres solutions ici organiseront une exception "non prise en charge sur cette plate-forme" si nécessaire sur le noyau .NET.



6
votes

Voici une implémentation pure C #, de Vérification de Google Play Signatures sur .NET .

Créer un projet d'application de la console Pour convertir la clé publique au format XML que RsacryptoServiceProvider code> attend. Ajouter Pemkeyloader.cs au projet d'application de la console. P>

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);
}


0 commentaires

0
votes

Ma solution basée sur Bouncycastle C # Nuget.

Remplacez le message, la signature et la touche avec votre une et testez-la. Pas besoin de Java d'obtenir le module ou l'exposant. P>

[TestMethod]
public void ValidadeMessageTest()
{
    //Base64-encoded RSA public key obtained from Google PlayStore, for the app. Go to DevelomentTools->Service & APIs
    var GooglePlayPK = "<put your key here>";

    bool validateReceipt(String message,String  messageSignature)
    {
        const String SIGNATURE_ALGORITHM = "SHA1";

        var rsaParameters = new RSAParameters();
        byte[] publicKeyBytes = Convert.FromBase64String(GooglePlayPK);
        AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKeyBytes);
        RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
        rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
        rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();

        using (var rsa = new RSACryptoServiceProvider())
        {
            var encoder = new ASCIIEncoding();
            byte[] bytesToVerify = encoder.GetBytes(message);
            byte[] signedBytes = Convert.FromBase64String(messageSignature);

                rsa.ImportParameters(rsaParameters);
                return  rsa.VerifyData(bytesToVerify, CryptoConfig.MapNameToOID(SIGNATURE_ALGORITHM), signedBytes);                   
        }        
    }
    //test your receipt
    Assert.IsTrue(validateReceipt(<original>, <signature>));
}


0 commentaires

0
votes

Pour toute personne qui pourrait toujours être intéressée, voici une solution C # pure C # (testée avec .NET 5.0): xxx


0 commentaires