Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
ILNAR_93
Android
220 / 220 / 23
Регистрация: 19.01.2013
Сообщений: 1,677
Записей в блоге: 3
#1

Проверка валидности покупки сторонним сервером - Программирование Android

20.11.2015, 13:23. Просмотров 309. Ответов 4
Метки нет (Все метки)

Возможно ли следующее:

Андроид устройства покупает контент через гугл и полученный JSON ответ отправляет на свой сервер, а этот сервер уже запрашивает сервер google на валидность покупки отправляя туда тот же JSON(идентификатор покупки)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2015, 13:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проверка валидности покупки сторонним сервером (Программирование Android):

Проверка покупки - Программирование Android
Всем привет, не получается сделать проверку на покупку. Вот такой код: mHelper.enableDebugLogging(true); ...

Связь со сторонним сервером - PHP Сети
Здравствуйте, форумчане. Есть вопрос по поводу реализации получения данных с другого сервера. Я хочу описать действия, а вам если не...

Проверка валидности строк - Visual Basic .NET
Здравствуйте. Возникла необходимость проверить структуру документа на соответствие маске перед внесением в него изменений. Для...

Проверка валидности xml - Java EE
Всем доброго времени! В общем-то все просто: есть xml файл, который затем обрабатывается с помощью JAXB. Но перед тем как его...

Проверка валидности email - JavaScript
Код проверяет заполнены ли поля: if ( posName.value == '') { alert("Введите Ваше имя"); posName.focus(); return; } if...

Проверка валидности указателя - C++
Привет! Есть ли в С++ нормальный метод проверки валидности указателя? Разумеется, что бы софт при этом не падал :D Мне нужно...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,649
Завершенные тесты: 1
20.11.2015, 13:24 #2
ILNAR_93, ага, именно так и нужно проверять.
ILNAR_93
Android
220 / 220 / 23
Регистрация: 19.01.2013
Сообщений: 1,677
Записей в блоге: 3
20.11.2015, 14:00  [ТС] #3
Spelcrawler, не подскажешь куда копать?)

Вот это не то?
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function verify_market_in_app($signed_data, $signature, $public_key_base64) 
{
 $key = "-----BEGIN PUBLIC KEY-----\n".
  chunk_split($public_key_base64, 64,"\n").
  '-----END PUBLIC KEY-----';   
 //using PHP to create an RSA key
 $key = openssl_get_publickey($key);
 //$signature should be in binary format, but it comes as BASE64. 
 //So, I'll convert it.
 $signature = base64_decode($signature);   
 //using PHP's native support to verify the signature
 $result = openssl_verify(
   $signed_data,
   $signature,
   $key,
   OPENSSL_ALGO_SHA1);
 if (0 === $result) 
 {
  return false;
 }
 else if (1 !== $result)
 {
  return false;
 }
 else 
 {
  return true;
 }
}
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,649
Завершенные тесты: 1
20.11.2015, 14:03 #4
ILNAR_93, по серверной части не могу помочь. Но выглядит рабочим.
ILNAR_93
Android
220 / 220 / 23
Регистрация: 19.01.2013
Сообщений: 1,677
Записей в блоге: 3
03.12.2015, 16:36  [ТС] #5
Проверка валидности посредством C#

Ответ от suvitruf
Когда приходит результат покупки, то в поле `inapp_signed_data` у `Intent`'а будет сигнатура.
Теперь вам нужен RSA. Для C# вам надо его сгенерировать из публичного ключа из вашей консоли разработчика в GP:

C#
1
2
3
const string MY_BASE64_PUBLIC_KEY = "Ваш base64 Google публичный ключ";
    RSACryptoServiceProvider provider = PEMKeyLoader.CryptoServiceProviderFromPublicKeyInfo(MY_BASE64_PUBLIC_KEY);
    string xmlPublicKey = provider.ToXmlString(false);
Вот класс для этого:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace PublicKeyConvert
    {
        public class PEMKeyLoader
        {
    
            // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
            static byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
    
            private static bool CompareBytearrays(byte[] a, byte[] b)
            {
                if (a.Length != b.Length)
                    return false;
                int i = 0;
                foreach (byte c in a)
                {
                    if (c != b[i])
                        return false;
                    i++;
                }
                return true;
            }
    
            public static RSACryptoServiceProvider CryptoServiceProviderFromPublicKeyInfo(byte[] x509key)
            {
                byte[] seq = new byte[15];
                int x509size;
    
                if (x509key == null || x509key.Length == 0)
                    return null;
                
                x509size = x509key.Length;
    
                // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------
                MemoryStream mem = new MemoryStream(x509key);
                BinaryReader binr = new BinaryReader(mem);    //wrap Memory Stream with BinaryReader for easy reading
                byte bt = 0;
                ushort twobytes = 0;
    
                try
                {
                    twobytes = binr.ReadUInt16();
                    if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                        binr.ReadByte();    //advance 1 byte
                    else if (twobytes == 0x8230)
                        binr.ReadInt16();   //advance 2 bytes
                    else
                        return null;
    
                    seq = binr.ReadBytes(15);       //read the Sequence OID
                    if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct
                        return null;
    
                    twobytes = binr.ReadUInt16();
                    if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
                        binr.ReadByte();    //advance 1 byte
                    else if (twobytes == 0x8203)
                        binr.ReadInt16();   //advance 2 bytes
                    else
                        return null;
    
                    bt = binr.ReadByte();
                    if (bt != 0x00)     //expect null byte next
                        return null;
    
                    twobytes = binr.ReadUInt16();
                    if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                        binr.ReadByte();    //advance 1 byte
                    else if (twobytes == 0x8230)
                        binr.ReadInt16();   //advance 2 bytes
                    else
                        return null;
    
                    twobytes = binr.ReadUInt16();
                    byte lowbyte = 0x00;
                    byte highbyte = 0x00;
    
                    if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
                        lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus
                    else if (twobytes == 0x8202)
                    {
                        highbyte = binr.ReadByte(); //advance 2 bytes
                        lowbyte = binr.ReadByte();
                    }
                    else
                        return null;
                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order
                    int modsize = BitConverter.ToInt32(modint, 0);
    
                    int firstbyte = binr.PeekChar();
                    if (firstbyte == 0x00)
                    {   //if first byte (highest order) of modulus is zero, don't include it
                        binr.ReadByte();    //skip this null byte
                        modsize -= 1;   //reduce modulus buffer size by 1
                    }
    
                    byte[] modulus = binr.ReadBytes(modsize);   //read the modulus bytes
    
                    if (binr.ReadByte() != 0x02)            //expect an Integer for the exponent data
                        return null;
                    int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)
                    byte[] exponent = binr.ReadBytes(expbytes);
    
    
                    // ------- create RSACryptoServiceProvider instance and initialize with public key -----
                    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                    RSAParameters RSAKeyInfo = new RSAParameters();
                    RSAKeyInfo.Modulus = modulus;
                    RSAKeyInfo.Exponent = exponent;
                    RSA.ImportParameters(RSAKeyInfo);
    
                    return RSA;
                }
                finally
                {
                    binr.Close();
                }
            }
    
            public static RSACryptoServiceProvider CryptoServiceProviderFromPublicKeyInfo(String base64EncodedKey)
            {
                try
                {
                    //see if the file is a valid Base64 encoded cert
                    return CryptoServiceProviderFromPublicKeyInfo(Convert.FromBase64String(base64EncodedKey));
                }
                catch (System.FormatException)
                {
                }
    
                return null;
            }
    
            public static byte[] X509KeyFromFile(String filename)
            {
                byte[] x509key;
    
                if (String.IsNullOrWhiteSpace(filename) || !File.Exists(filename))
                    return null;
    
                StreamReader sr = File.OpenText(filename);
                String filestr = sr.ReadToEnd();
                sr.Close();
                StringBuilder sb = new StringBuilder(filestr);
                sb.Replace("-----BEGIN PUBLIC KEY-----", "");  //remove headers/footers, if present
                sb.Replace("-----END PUBLIC KEY-----", "");
    
                try
                {   
                    //see if the file is a valid Base64 encoded cert
                    x509key = Convert.FromBase64String(sb.ToString());
                }
                catch (System.FormatException)
                {       
                    //if not a b64-encoded publiccert, assume it's binary
                    Stream stream = new FileStream(filename, FileMode.Open);
                    int datalen = (int)stream.Length;
                    x509key = new byte[datalen];
                    stream.Read(x509key, 0, datalen);
                    stream.Close();
                }
    
                return x509key;
            }
    
        }
    }
Теперь можно проверять подпись сообщения:


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
 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);
    }
`message` - это ваш JSON.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.12.2015, 16:36
Привет! Вот еще темы с ответами:

Проверка валидности библиотеки - C++ Qt
Вечер добрый. Прошу помочь по достаточно простому вопросу. У меня есть динамическая библиотека. Точнее она не совсем есть. Она может...

Проверка валидности числа - PHP
Добрый день. preg_match("/^\d{6}$/i", @$_POST) Если я ввожу 1 или 2 код выполняется правильно. Но злодей может написать и -1 или -2....

Проверка валидности в libxml++ - C++
Подскажите, как с помощью этой библиотеки можно проверить валидность документа на соответствие XML. Вариант через исключение при создании...

Проверка валидности xml в yii2 - PHP
Добрый день. Есть файл test.xml и схема test.xsd. Необходимо проверить файл на соответствие схеме. Помогите реализовать это в Yii2. Заранее...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
03.12.2015, 16:36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru