HI, All
In-app are cheated by Freedom or LuckyPatcher application. So each purchase must be checked, verified that really made on Google side. Google signs his reply.
Please, help to make working module for this verification.
I read https://www.b4x.com/android/forum/threads/inapp_purchase_data-and-inapp_data_signature.46545/ , googled a lot and made this sketch:
No idea right or not way, please, suggest, i did not try yet.
In-app are cheated by Freedom or LuckyPatcher application. So each purchase must be checked, verified that really made on Google side. Google signs his reply.
Please, help to make working module for this verification.
I read https://www.b4x.com/android/forum/threads/inapp_purchase_data-and-inapp_data_signature.46545/ , googled a lot and made this sketch:
No idea right or not way, please, suggest, i did not try yet.
B4X:
'Code module
'Subs in this code module will be accessible from all modules.
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Private nativeMe As JavaObject
End Sub
'PublicKey = RSA public encription key like "MIIBIjANBgkqhkiG9w0BAQ....." from Google Play app API console
Sub Verify (PublicKey As String, Product As Purchase)
Dim OriginalJson, base64Signature As String
Dim jo As JavaObject = Product
base64Signature = jo.RunMethod("getSignature", Null)
OriginalJson = jo.RunMethod("getOriginalJson", Null)
nativeMe.InitializeContext
Dim Params(3) As String
Params(0) = PublicKey 'RSA public encription key like "MIIBIjANBgkqhkiG9w0BAQ....." from Google Play app API console
Params(1) = OriginalJson 'signedData
Params(2) = base64Signature 'signature
Dim result As Boolean = nativeMe.RunMethod("verify", Params)
Log("result=" & result)
End Sub
#If JAVA
public class Security {
public final static Logger logger = Logger.getLogger(Security.class.getName());
private static final String KEY_FACTORY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* 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);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
catch (InvalidKeySpecException e) {
logger.error("Invalid key specification.", e);
throw new IllegalArgumentException(e);
}
catch (Base64DecoderException e) {
logger.error("Base64 decoding failed.", 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 verify(PublicKey publicKey, String signedData, String signature) {
Signature sig;
try {
sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
byte[] decodedSig = Base64.decode(signature);
if (!sig.verify(decodedSig)) {
logger.error("Signature verification failed.");
return false;
}
return true;
}
catch (NoSuchAlgorithmException e) {
logger.error("NoSuchAlgorithmException.");
}
catch (InvalidKeyException e) {
logger.error("Invalid key specification.");
}
catch (SignatureException e) {
logger.error("Signature exception.");
}
catch (Base64DecoderException e) {
logger.error("Base64 decoding failed.");
}
return false;
}
}
#End If