APK 변조 대비하기
1.런타임에 Signing 인증서 확인하기
PackageInfo 를 이용해 런타임에 Signing 인증서를 가져올 수 있다. 이를 서버로 보내어, 현재 앱의 인증서가 제대로 된 인증서인지 변조된 인증서인지를 분별하여 앱의 실행을 제한하는 방법이다.방법
- keystore파일의 SHA-1키를 확인하여 서버에 저장한다.
 
keytool -exportcert -alias <Alias 이름> -keystore <키스토어 파일경로> | openssl sha1 -binary | openssl base64
//예시
keytool -exportcert -alias DISC -keystore JBS.keystore  | openssl sha1 -binary | openssl base64
- 앱에서 현재 Signing된 인증서 정보를 가져온다.
 
public static void checkAppSignatureInServer(Context context, Callback callback) {
    try {
        @SuppressLint("PackageManagerGetSignatures")
        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
        
        //안드로이드는 이론상 여러 키스토어로 Signing 가능하다고 하지만,
        //일반적으로는 하나의 키스토어로만 Signing을 하므로, signatures의 첫번째 값을 이용한다.
        Signature signature = packageInfo.signatures[0];
        final String currentSignature = obtainSignatureString(signature);
        fetchServer(currentSignature, callback);
    } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}
private static void fetchServer(String signature, Callback callback) {
    //TODO::Fill in server logic
    callback.onFinishCheck(ValidationEnum.VALID);
}
2.인스톨러 확인
모든 앱은 자신이 어떤 인스톨러로부터 인스톨되었는지를 알 수 있도록 인스톨러의 identifier를 가지고 있다. 이 값을 확인하여, 등록된 인스톨러가 아닐 경우에 앱의 사용을 제한하는 방법이 있다.
방법
- 인스톨러의 identifier를 확인한다.
 
- 구글 : com.android.vending
 - 다른 스토어의 인스톨러 id 확인 필요.
 
- 앱의 인스톨러를 확인한다.
 
public static boolean verifyGoogleInstaller(Context context) {
    final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
    return installer != null && installer.startsWith("com.android.vending");
}