jamesmontemagno / InAppBillingPlugin

Cross-platform In App Billing Plugin for .NET
MIT License
651 stars 152 forks source link

InAppBillingSecurity.GeneratePublicKey gives Java.Lang.IllegalArgumentException #356

Closed CDrosos closed 2 years ago

CDrosos commented 3 years ago

I have made the billing functions exactly as the documentation and while in versions before 4 in was working now in a new app im getting this exception

Plugin.InAppBilling
InAppBillingImplementation+InAppBillingSecurity.GeneratePublicKey (System.String encodedPublicKey)
Plugin.InAppBilling
InAppBillingImplementation+InAppBillingSecurity.VerifyPurchase (System.String publicKey, System.String signedData, System.String signature)
KinoStats.Helpers
InAppBillingVerify.VerifyPurchase (System.String signedData, System.String signature, System.String productId, System.String transactionId)
Plugin.InAppBilling
InAppBillingImplementation.PurchaseAsync (System.String productSku, System.String itemType, Plugin.InAppBilling.IInAppBillingVerifyPurchase verifyPurchase)
Plugin.InAppBilling
InAppBillingImplementation.PurchaseAsync (System.String productId, Plugin.InAppBilling.ItemType itemType, Plugin.InAppBilling.IInAppBillingVerifyPurchase verifyPurchase)

Im pretty sure the Verify section is exactly as in the documentation and the public key is the correct one, does anybody know what is this exception about?

For public key im using public RSA with Base64 encoding key that is found from Google Play developer console/ Financial reports/ monetization-setup, is this the correct one?

This is also how i verify the purchase

public class InAppBillingVerify : IInAppBillingVerifyPurchase
    {
        const string key1 =
            @"123";

        const string key2 =
            @"456";

        const string key3 =
            @"789";

        public Task<bool> VerifyPurchase(string signedData, string signature, string productId = null,
            string transactionId = null)
        {

            var key1Transform = InAppBillingImplementation.InAppBillingSecurity.TransformString(key1, 1);
            var key2Transform = InAppBillingImplementation.InAppBillingSecurity.TransformString(key2, 2);
            var key3Transform = InAppBillingImplementation.InAppBillingSecurity.TransformString(key3, 3);

            return Task.FromResult(
                InAppBillingImplementation.InAppBillingSecurity.VerifyPurchase(
                    key1Transform + key2Transform + key3Transform, signedData, signature));
        }

If for example my public key was "123456789";

CDrosos commented 3 years ago

Im using version 4.0.2

CDrosos commented 3 years ago

I guess the error comes from:

public static IPublicKey GeneratePublicKey(string encodedPublicKey)
            {
                try
                {
                    var keyFactory = KeyFactory.GetInstance(KeyFactoryAlgorithm);
                    return keyFactory.GeneratePublic(new X509EncodedKeySpec(Android.Util.Base64.Decode(encodedPublicKey, 0)));
                }
                catch (NoSuchAlgorithmException e)
                {
                    Console.WriteLine(e.Message);
                    throw new RuntimeException(e);
                }
                catch (Java.Lang.Exception e)
                {
                    Console.WriteLine(e.Message);
                    throw new IllegalArgumentException();
                }
            }

Does anyone know why?

assassin316 commented 3 years ago

I'm having the same issue. Doing some testing on Android purchases and now getting this error. The error happens at:

keyFactory.GeneratePublic(new X509EncodedKeySpec(Android.Util.Base64.Decode(encodedPublicKey, 0)));

Just to clarify, I followed the docs exactly as stated using the XOR key idea and am getting this error. Can it be due to "testing" and the fact that the purchases are not real purchases?

@CDrosos Have you figured out a workaround since you've posted this issue?

CDrosos commented 3 years ago

@assassin316 no i just return true and avoid checking the key because it always return an error. When i was using version 3 of InAppBilling the same code was working that it is not working on version 4. So for now i just return true

public Task<bool> VerifyPurchase(string signedData, string signature, string productId = null,
            string transactionId = null)
        {
            return Task.FromResult(true);
        }

I had test it in public release with real purchases and was not working

jamesmontemagno commented 3 years ago

I would need to look at this, i haven't used it in a long while. I am not sure if the signed data comes back or how it works anymore.

jamesmontemagno commented 2 years ago

I am removing this from the code and just documenting it.