/[projects]/android/TrainInfo/src/com/example/android/trivialdrivesample/util/Security.java
ViewVC logotype

Contents of /android/TrainInfo/src/com/example/android/trivialdrivesample/util/Security.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2123 - (show annotations) (download)
Wed Mar 5 12:11:16 2014 UTC (10 years, 2 months ago) by torben
File size: 5033 byte(s)
Add billing code
1 /* Copyright (c) 2012 Google Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 package com.example.android.trivialdrivesample.util;
17
18 import android.text.TextUtils;
19 import android.util.Log;
20
21 import org.json.JSONException;
22 import org.json.JSONObject;
23
24
25 import java.security.InvalidKeyException;
26 import java.security.KeyFactory;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.PublicKey;
29 import java.security.Signature;
30 import java.security.SignatureException;
31 import java.security.spec.InvalidKeySpecException;
32 import java.security.spec.X509EncodedKeySpec;
33
34 /**
35 * Security-related methods. For a secure implementation, all of this code
36 * should be implemented on a server that communicates with the
37 * application on the device. For the sake of simplicity and clarity of this
38 * example, this code is included here and is executed on the device. If you
39 * must verify the purchases on the phone, you should obfuscate this code to
40 * make it harder for an attacker to replace the code with stubs that treat all
41 * purchases as verified.
42 */
43 public class Security {
44 private static final String TAG = "IABUtil/Security";
45
46 private static final String KEY_FACTORY_ALGORITHM = "RSA";
47 private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
48
49 /**
50 * Verifies that the data was signed with the given signature, and returns
51 * the verified purchase. The data is in JSON format and signed
52 * with a private key. The data also contains the {@link PurchaseState}
53 * and product ID of the purchase.
54 * @param base64PublicKey the base64-encoded public key to use for verifying.
55 * @param signedData the signed JSON string (signed, not encrypted)
56 * @param signature the signature for the data, signed with the private key
57 */
58 public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
59 if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
60 TextUtils.isEmpty(signature)) {
61 Log.e(TAG, "Purchase verification failed: missing data.");
62 return false;
63 }
64
65 PublicKey key = Security.generatePublicKey(base64PublicKey);
66 return Security.verify(key, signedData, signature);
67 }
68
69 /**
70 * Generates a PublicKey instance from a string containing the
71 * Base64-encoded public key.
72 *
73 * @param encodedPublicKey Base64-encoded public key
74 * @throws IllegalArgumentException if encodedPublicKey is invalid
75 */
76 public static PublicKey generatePublicKey(String encodedPublicKey) {
77 try {
78 byte[] decodedKey = Base64.decode(encodedPublicKey);
79 KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
80 return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
81 } catch (NoSuchAlgorithmException e) {
82 throw new RuntimeException(e);
83 } catch (InvalidKeySpecException e) {
84 Log.e(TAG, "Invalid key specification.");
85 throw new IllegalArgumentException(e);
86 } catch (Base64DecoderException e) {
87 Log.e(TAG, "Base64 decoding failed.");
88 throw new IllegalArgumentException(e);
89 }
90 }
91
92 /**
93 * Verifies that the signature from the server matches the computed
94 * signature on the data. Returns true if the data is correctly signed.
95 *
96 * @param publicKey public key associated with the developer account
97 * @param signedData signed data from server
98 * @param signature server signature
99 * @return true if the data and signature match
100 */
101 public static boolean verify(PublicKey publicKey, String signedData, String signature) {
102 Signature sig;
103 try {
104 sig = Signature.getInstance(SIGNATURE_ALGORITHM);
105 sig.initVerify(publicKey);
106 sig.update(signedData.getBytes());
107 if (!sig.verify(Base64.decode(signature))) {
108 Log.e(TAG, "Signature verification failed.");
109 return false;
110 }
111 return true;
112 } catch (NoSuchAlgorithmException e) {
113 Log.e(TAG, "NoSuchAlgorithmException.");
114 } catch (InvalidKeyException e) {
115 Log.e(TAG, "Invalid key specification.");
116 } catch (SignatureException e) {
117 Log.e(TAG, "Signature exception.");
118 } catch (Base64DecoderException e) {
119 Log.e(TAG, "Base64 decoding failed.");
120 }
121 return false;
122 }
123 }

  ViewVC Help
Powered by ViewVC 1.1.20