2017년 2월 14일 화요일

[안드로이드] apk 위/변조 대비하기

APK 변조 대비하기

1.런타임에 Signing 인증서 확인하기

PackageInfo 를 이용해 런타임에 Signing 인증서를 가져올 수 있다. 이를 서버로 보내어, 현재 앱의 인증서가 제대로 된 인증서인지 변조된 인증서인지를 분별하여 앱의 실행을 제한하는 방법이다.

방법

  1. 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
  1. 앱에서 현재 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를 가지고 있다. 이 값을 확인하여, 등록된 인스톨러가 아닐 경우에 앱의 사용을 제한하는 방법이 있다.

방법

  1. 인스톨러의 identifier를 확인한다.
  • 구글 : com.android.vending
  • 다른 스토어의 인스톨러 id 확인 필요.
  1. 앱의 인스톨러를 확인한다.
public static boolean verifyGoogleInstaller(Context context) {
    final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
    return installer != null && installer.startsWith("com.android.vending");
}