Android-приложение для выставления счетов Проверка получения в Dot Net (C #)

У меня есть приложение для Android, которое предоставляет биллинг в приложении, и у нас есть наш сервер приложений, к которому приложение Android подключается для предоставления услуг пользователю, при покупке в приложении мы хотим отправить квитанцию ​​на сервер для проверки.

Теперь проблема в том, что я не знаю, как преобразовать файл Security.java в net net (C #), поскольку наш сервер написан в dot net

ПРИМЕЧАНИЕ. Этот файл поставляется с биллинговым подключением Android в одном приложении, которое обеспечивает функции подписи сообщений. Мне просто нужен их эквивалент в сети точек.

Более подробную информацию об этой проблеме можно найти по адресу http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/66bb5683-fde6-47ca-92d7-de255cc8655a

Вот чистая реализация C #, от проверки подписи Google Play на .Net .

Создайте проект консольного приложения для преобразования открытого ключа в формат XML, который ожидает RSACryptoServiceProvider . Добавьте 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."; } } 

Запуск этого консольного приложения выводит (на консоль) формат XML, который ожидает RSACryptoServiceProvider .

Теперь, когда у вас есть открытый ключ в формате 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); } 

Я нашел решение, для достижения вам сначала нужно преобразовать формат открытого ключа, так как точка-сеть использует в качестве входного сигнала другой ключ.

Я не знаю других способов, но мы можем получить ключ с чистым точечным ключом, используя код Java, который вы должны запускать только один раз, чтобы создать открытый сетевой ключ RSA. (Это рекомендуется только в том случае, если данная публика не изменяется быстро, например, в случае выставления счетов на рынке Android в приложении)

После Java Code работал для меня

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

Теперь, чтобы проверить цифровую подпись, вы можете использовать следующий код в вашей сетевой сети (c #), если GCHO_PUB_KEY_EXP – это ваш Exponent, а 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)); } } 

Надеюсь, это сработает для всех, как для меня. благодаря

Кредит переходит к Code Project Artical

Для всех людей, которым необходимо проверить подпись, это полная реализация c #, использующая dll BouncyCastle для оказания помощи.

Если вы загрузите класс с помощью открытого ключа Google, вы сможете проверить подписи без необходимости использования какого-либо кода Java. Получайте удовольствие от этого. 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 для поиска peeps, вот полный файл Java и функция в 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; } } 

Просто добавьте в новый Java-проект и запустите приложение java с точкой прерывания (int i = 0;), чтобы извлечь ключи, код не мой, только что связанный мной, реквизит оригинального автора, ссылку выше

И 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