Facturación en la aplicación de Android Verificación de la recepción en la red de puntos (C #)

Tengo una aplicación de Android que proporciona facturación en la aplicación y tenemos nuestro servidor de aplicaciones a la que se conecta la aplicación android para proporcionar servicios al usuario, en la compra en la aplicación queremos enviar confirmación al servidor para el proceso de verificación.

Ahora el problema es que no sé cómo convertir el archivo Security.java en punto net (C #) como nuestro servidor está escrito en dot net

NOTA: Este archivo viene con la aplicación de Android en la aplicación misma aplicación que proporciona funciones de firma de mensajes sólo necesito su equivalente en la red de puntos.

Más información sobre este problema está disponible en http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/66bb5683-fde6-47ca-92d7-de255cc8655a

Esta es una implementación de C # pura, desde Comprobar las firmas de Google Play en .Net .

Cree un proyecto de aplicación de consola para convertir la clave pública en el formato XML que RSACryptoServiceProvider espera. Agregue PEMKeyLoader.cs al proyecto de aplicación de consola.

 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."; } } 

Ejecutar esa aplicación de consola mostrará (a la consola) el formato XML que RSACryptoServiceProvider espera.

Ahora que tiene su clave pública con formato XML, puede usarla para verificar las firmas:

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

He encontrado la solución, para lograr que primero tiene que convertir el formato de clave pública como punto net utiliza tipo de clave diferente como una entrada.

No sé las otras maneras pero podemos conseguir la llave del formato del net del punto usando un código de java que usted tiene que funcionar solamente una vez para generar la llave pública RSA favorable de la red del punto. (Esto sólo se recomienda cuando el público dado no cambia rápidamente, por ejemplo, en el caso de la facturación en la aplicación de Android en la aplicación)

Siguiente código de Java trabajado para mí

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

Ahora, para verificar la firma digital, puede utilizar el código siguiente en su programa de red de puntos (c #) siempre que GCHO_PUB_KEY_EXP sea su exponente y GCHO_PUB_KEY_MOD sea su módulo extraído por código Java anterior.

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

Espero que funcione para todos como trabajado para mí. Gracias

Crédito va al proyecto de código Artical

Para todas las personas que necesitan para verificar la firma aquí es una implementación c # completa con la dll BouncyCastle para ayudar.

Si alimenta la clase con su clave pública de Google, podrá verificar las firmas sin necesidad de ningún código Java. Diviértete con eso. Grtz martien

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

FYI para la búsqueda peeps, aquí está el archivo completo de Java, y la función en VB.NET.

 /** * <p>Title: RSA Security</p> * Description: This class generates a RSA private and public key, reinstantiates * the keys from the corresponding key files.It also generates compatible .Net Public Key, * which we will read later in C# program using .Net Securtiy Framework * The reinstantiated keys are used to sign and verify the given data.</p> * * @author Shaheryar * @version 1.0 */ import java.security.*; import java.security.spec.*; import java.io.*; import java.security.interfaces.*; import java.security.cert.*; import javax.xml.transform.stream.*; import javax.xml.transform.dom.*; import javax.xml.transform.*; import org.w3c.dom.*; import javax.xml.parsers.*; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class SecurityManager { private KeyPairGenerator keyGen; //Key pair generator for RSA private PrivateKey privateKey; // Private Key Class private PublicKey publicKey; // Public Key Class private KeyPair keypair; // KeyPair Class private Signature sign; // Signature, used to sign the data private String PRIVATE_KEY_FILE; // Private key file. private String PUBLIC_KEY_FILE; // Public key file. private String DOT_NET_PUBLIC_KEY_FILE; // File to store .Net Compatible Key Data /** * Default Constructor. Instantiates the key paths and signature algorithm. * @throws IOException * @throws InvalidKeySpecException * @throws NoSuchAlgorithmException */ public SecurityManager() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { } public static void main(String args[]) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException{ GenerateDotNetKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp6340BNzismmb/n98sTcYfNEmmzNGumdWnK1e7NNWntM6mjZMnQaVZ9HiJKmMgtn69dAU4gaMVUWACDsuup1GBxN8dLgDbtR26M0u1jf1G8AQehcKfqxqSYzxKquXXotffdYsJPpjseZbi96Y7j47kz9CjNP3y1BzjJNTWQUx9fc9e2Bpsi0GtqJ8porPBuIGTjcCnlKM14tIv6YlHtECW1L1wcOBkoj/5liI1nhlYDth/DNXg1OY11JqIIP1fO2vQPtKEpdtcTBTjmB9M45O1N8K/shTcMntFjwVTpL0hRd+eaN1bUjpMvrhFik0VcF/ZNN6Hn0Coqe+ey18dLosQIDAQAB"); } public static void 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 = stripLeadingZeros1(modulusBytes); BASE64Encoder encoder = new BASE64Encoder(); String modulusB64 = encoder.encode(modulusBytes); String exponentB64 = encoder.encode(exponentBytes); int i=0; // return new DotNetRSA(modulusB64, exponentB64); } private static byte[] stripLeadingZeros1(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; } } 

Simplemente agregue a un nuevo proyecto de Java y ejecute como una aplicación java con un punto de interrupción (int i = 0;) para extraer sus claves, código no mío, sólo bodged por mí, apoyos al autor original, enlace anterior

Y VB.NET

 Private Function VerifyDataSignature(ByVal data As String, ByVal sign As String) As Boolean Using rsa As New RSACryptoServiceProvider() Dim rsaKeyInfo As RSAParameters = New RSAParameters() rsaKeyInfo.Exponent = Convert.FromBase64String("ExponentFromJava") rsaKeyInfo.Modulus = Convert.FromBase64String("ModulusFromJava") rsa.ImportParameters(rsaKeyInfo) Return rsa.VerifyData(Encoding.ASCII.GetBytes(data), "SHA1", Convert.FromBase64String(sign)) End Using End Function 
  • Android Studio: falló la instalación desde que APK no se firmó
  • Significado de "AES" cifra en Android?
  • ¿Llamadas GSM con RILD en Android?
  • Cifrar con Node.js módulo Crypto y descifrar con Java (en la aplicación de Android)
  • Encriptación de clave pública / privada Android-PHP
  • Extraer datos de la clave pública de RSA
  • MD5 hashing en Android
  • Cómo hash una cadena en Android?
  • Buscar código fuente de Android?
  • Mensaje firmado usando OpenSSL; No se puede verificar con Android Java
  • Android CryptoObject uso en huellas dactilares
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.