Security Best Practices

Due to the sensitive data we use on the client side, such as "private key" and "amount," we are open to attack via a reverse engineering. Therefore, we must secure our application.

Secure App Payment Type

# Securing Only Premium Feature

  • as much as possible, verify whether the user has made a app purchase in every activity. This is to prevent the user from using the app without paying.

To check if user has made a app purchased, ChapaUtil.isCurrentPlanIn("your-app-plan-name","other-valid-plan","....") method. It returns true if user has made a app purchase on the listed app-plans and false if user hasn't made in listed app-plan a payment.

  • Method 1

on Activity onCreate method, check if user has made a app purchase. If user hasn't made a app purchase, redirect user to PaymentActivity or Close the app.

  • Method 2

the above method is repetitive, so we can create a BaseActivity class and extend ALL ACTIVITY that require purchase from it. Then in BaseActivity class, check if user has made a app purchase. If user hasn't made a app purchase, redirect user to PaymentActivity or Close the app.

public class BasicActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(!ChapaUtil.isCurrentPlanIn("Premium")) {
            // to redirect user to payment activity
            Intent intent = new Intent(this, PaymentActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            // to Exit the app
            // System.exit(0);
            // to close current activity
            // finish();
            // or you can do anything you want
        }
    }
}
// USAGE
// change every activity require app-purchase to extend BasicActivity
class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (!ChapaUtil.isCurrentPlanIn("Premium")) {
            // to redirect user to payment activity
            val intent = Intent(this, PaymentActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
            // to Exit the app
            // System.exit(0);
            // to close current activity
            // finish();
            // or you can do anything you want
        }
    }
}

// USAGE
// change every activity require app-purchase to extend BasicActivity

Encrypt Payment Data

  • Encrypt Amount and chapa secret Key and item-key.
    To encrypt data, use Cipher.encrypt method.
Log.d("Encrypted ",
        "amount" + Cipher.encrypt(this,"19.9") + 
        "item-key" + Cipher.encrypt(this,"gold") +
        "item-value" + Cipher.encrypt(this,"300"));

// copy the logged encrypted data from logcat  
try {
   ItemPayment gold =  new ItemPayment(
        this,
        Double.parseDouble(Cipher.decrypt(this, "C5F373E141957172C4F130A65BFE70B9")), // amount
        Cipher.decrypt(this, "DAABD31A834EEC8E3EE29C819AFD6091"), // itemKey
        Integer.parseInt(Cipher.decrypt(this, "E6D33CB6CBFB48212745A53469AC5CC0")), // itemValue
        ItemProperties.ADD
     );
} catch (ChapaError e) {
   e.printStackTrace(); // UNSUPPORTED DATA-TYPE
}
Log.d("Encrypted ",
        "amount ${Cipher.encrypt(this,"19.9")}" + 
        "item-key ${Cipher.encrypt(this,"gold")}" +
        "item-value ${Cipher.encrypt(this,"300")}")

// copy the logged encrypted data from logcat  
try {            
   val gold =  ItemPayment(
        this,
        Cipher.decrypt(this, "C5F373E141957172C4F130A65BFE70B9").toDouble(), // amount
        Cipher.decrypt(this, "DAABD31A834EEC8E3EE29C819AFD6091"), // itemKey
        Cipher.decrypt(this, "E6D33CB6CBFB48212745A53469AC5CC0").toInt(), // itemValue
        ItemProperties.ADD
    )
} catch (e: ChapaError) {
    Log.e("Error", e.message) // UNSUPPORTED DATA TYPE
}

Other Security Best Practice

  • Always Use Proguard to obfuscate your code. This will make it harder for attackers to reverse engineer your code. Learn moreopen in new window

Learn more about App Security Best Practiceopen in new window