검색결과 리스트
글
Java server side Apple IAP and Google Play IAP verification class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
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;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
/**
* Apple IAP and Google Play In-app Billing Verification Class
*
*/
public class IapVerification {
static Logger logger = Logger.getLogger(IapVerification.class);
public static final String VERIFICATION_URL_REAL = "https://buy.itunes.apple.com/verifyReceipt";
public static final String VERIFICATION_URL_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt";
/**
* @return int
* @param receipt
* @param isTest
* @return 0: fail, 1: success, -1 : urus hacking
* @throws IOException
*/
public static int verifyApplePurchase(String receipt, boolean isTest) throws IOException {
String returnedString ;
if (isTest)
{
returnedString = verifyAppleReceiptData(VERIFICATION_URL_SANDBOX, receipt);
} else {
returnedString = verifyAppleReceiptData(VERIFICATION_URL_REAL, receipt);
}
ObjectMapper mapper = new ObjectMapper();
JsonNode resultObject = mapper.readTree(returnedString);
int resultStatus = Integer.parseInt(resultObject.get("status").toString());
if (resultStatus != 0)
{
// urus hacking check.
try {
String decodedText = new String(Base64.decodeBase64(receipt
.getBytes()), "UTF-8");
if (decodedText != null && decodedText.startsWith("com.urus")) {
return -1;
}
} catch (Exception base64DecodeException) {
logger.error(base64DecodeException.getMessage());
}
return 0;
}
return 1;
}
/**
* @author Kim Seong Su
* @return String
* @param urladdress
* @param receiptData
* @return result string
* @throws IOException
*/
private static String verifyAppleReceiptData(String urladdress, String receiptData) throws IOException {
URL url = null;
URLConnection conn = null;
OutputStreamWriter osw = null;
BufferedReader br = null;
StringBuffer sb = new StringBuffer();
try {
String jsonData = "{" +
"\"receipt-data\" : \"" + receiptData + "\"," +
"}";
url = new URL(urladdress);
conn = url.openConnection();
conn.setDoOutput(true);
osw = new OutputStreamWriter(conn.getOutputStream());
osw.write(jsonData);
osw.flush();
// Get the response
br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
sb = new StringBuffer();
while ((line = br.readLine()) != null) {
// Process line...
sb.append(line);
}
} finally {
if (osw != null)
osw.close();
if (br != null)
br.close();
}
return sb.toString();
}
// --------------------- For Android --------------------------//
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 verifyAndroidPurchase(String base64PublicKey, String signedData, String signature) {
if (signedData == null) {
return false;
}
boolean verified = false;
if (!StringUtils.isEmpty(signature)) {
PublicKey key = IapVerification.generatePublicKey(base64PublicKey);
verified = IapVerification.verifyAndroidSignedData(key, signedData, signature);
if (!verified) {
return false;
}
}
return true;
}
/**
* 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.decodeBase64(encodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException(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 verifyAndroidSignedData(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.decodeBase64(signature))) {
return false;
}
return true;
} catch (NoSuchAlgorithmException e) {
logger.error(e.getMessage());
} catch (InvalidKeyException e) {
logger.error(e.getMessage());
} catch (SignatureException e) {
logger.error(e.getMessage());
}
return false;
}
}
'Programming' 카테고리의 다른 글
리눅스 한달 이상 지난 로그 삭제 크론. (0) | 2012.12.12 |
---|---|
Java server side Apple IAP and Google Play IAP verification class (0) | 2012.12.12 |
AWS EC2 Instance를 AMI로 만드는 방법. (0) | 2012.11.26 |
Maven 사용시 외부 Jar를 maven pom.xml에 추가하는 방법. (0) | 2012.11.05 |