2014-08-31 3 views
1

내 응용 프로그램에서 inapp 구매를 구현했습니다. 관리되는 응용 프로그램을 구입하면이 오류 로그가 나에게 표시됩니다. 왜 이런 일이 일어 났는지 말해 줄 수 있습니까? 여기Android 인앱 구매 V3

08-31 14:58:00.931: E/IABUtil/Security(31515): Purchase verification failed: missing data. 
08-31 14:58:00.931: E/viable(31515): Public key signature doesn't match! 

내 Security.java 클래스

/* Copyright (c) 2012 Google Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package Classes; 

import android.text.TextUtils; 
import android.util.Base64; 
import android.util.Log; 

import java.security.InvalidKeyException; 
import java.security.KeyFactory; 
import java.security.NoSuchAlgorithmException; 
import java.security.PublicKey; 
import java.security.Signature; 
import java.security.SignatureException; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.X509EncodedKeySpec; 

/** 
* Security-related methods. For a secure implementation, all of this code 
* should be implemented on a server that communicates with the 
* application on the device. For the sake of simplicity and clarity of this 
* example, this code is included here and is executed on the device. If you 
* must verify the purchases on the phone, you should obfuscate this code to 
* make it harder for an attacker to replace the code with stubs that treat all 
* purchases as verified. 
*/ 
class Security { 
    private static final String TAG = "IABUtil/Security"; 

    private static final String KEY_FACTORY_ALGORITHM = "RSA"; 
    private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; 


    /** 
    * Verifies that the data was signed with the given signature, and returns 
    * the verified purchase. The data is in JSON format and signed 
    * with a private key. The data also contains the {@link PurchaseState} 
    * and product ID of the purchase. 
    * @param base64PublicKey the base64-encoded public key to use for verifying. 
    * @param signedData the signed JSON string (signed, not encrypted) 
    * @param signature the signature for the data, signed with the private key 
    */ 
    public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) { 
     if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) || 
       TextUtils.isEmpty(signature)) { 
      Log.e(TAG, "Purchase verification failed: missing data."); 
      return false; 
     } 

     PublicKey key = Security.generatePublicKey(base64PublicKey); 
     return Security.verify(key, signedData, signature); 
    } 

    /** 
    * Generates a PublicKey instance from a string containing the 
    * Base64-encoded public key. 
    * 
    * @param encodedPublicKey Base64-encoded public key 
    * @throws IllegalArgumentException if encodedPublicKey is invalid 
    */ 
    public static PublicKey generatePublicKey(String encodedPublicKey) { 
     try { 
      byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT); 
      KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM); 
      return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey)); 
     } catch (NoSuchAlgorithmException e) { 
      throw new RuntimeException(e); 
     } catch (InvalidKeySpecException e) { 
      Log.e(TAG, "Invalid key specification."); 
      throw new IllegalArgumentException(e); 
     } catch (IllegalArgumentException e) { 
      Log.e(TAG, "Base64 decoding failed."); 
      throw e; 
     } 
    } 

    /** 
    * Verifies that the signature from the server matches the computed 
    * signature on the data. Returns true if the data is correctly signed. 
    * 
    * @param publicKey public key associated with the developer account 
    * @param signedData signed data from server 
    * @param signature server signature 
    * @return true if the data and signature match 
    */ 
    public static boolean verify(PublicKey publicKey, String signedData, String signature) { 
     Signature sig; 
     try { 
      sig = Signature.getInstance(SIGNATURE_ALGORITHM); 
      sig.initVerify(publicKey); 
      sig.update(signedData.getBytes()); 
      if (!sig.verify(Base64.decode(signature, Base64.DEFAULT))) { 
       Log.e(TAG, "Signature verification failed."); 
       return false; 
      } 
      return true; 
     } catch (NoSuchAlgorithmException e) { 
      Log.e(TAG, "NoSuchAlgorithmException."); 
     } catch (InvalidKeyException e) { 
      Log.e(TAG, "Invalid key specification."); 
     } catch (SignatureException e) { 
      Log.e(TAG, "Signature exception."); 
     } catch (IllegalArgumentException e) { 
      Log.e(TAG, "Base64 decoding failed."); 
     } 
     return false; 
    } 
} 

답변