본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] 디컴파일링시 Plain Text 로 노출되면 안 되는 정보들 숨기기

by 돼지왕 왕돼지 2015. 12. 24.
반응형

 [android] 디컴파일링시 Plain Text 로 노출되면 안 되는 정보들 숨기기


AES, base64, Character, Cipher, config, debug, decoding, decrypt, DECRYPT_MODE, default, Digest, doFinal, Encoding, encoding/decoding, encrypt, ENCRYPT_MODE, getPackageInfo, getSignedMode, GET_SIGNATURES, MessageDigest, PacakgeManager, packageinfo, Plain Text, SecretKey, SecretKeySpec, SHA, SHA-256, sign key, Signature, SIGNED_AS_DEVELOPMENT, utf-8, [android] 디컴파일링시 Plain Text 로 노출되면 안 되는 정보들 숨기기, 디컴파일, 디컴파일링, 보안, 보안 레벨, 안정, 안정성, 알고리즘, 인코딩, 정보 숨기기


-

아주 간단하게는 각 character 들에 특정값을 더하고 빼기정도를 하는 것으로 인코딩할 수 있다.
하지만 보안 레벨 측면에서는 상당히 조악한 방법으로, 

명석한 디컴파일러(사람기준)들은 이정도는 아주 간단하게 디코딩 할 수 있다.


-
그럼 어떻게 안정적으로 만들 수 있을까?
너무 어렵지 않으면서 나름 안정성을 줄 수 있는 방법은 sign key 에서 특정 값을 추출해서,
보안적으로 안정성이 높은 알고리즘으로 encoding/decoding 을 하면 된다.



Encrypt ( Encoding )

SecretKey key = null;

byte[] encryptedByte = null;

try{

PackageInfo packageInfo = getPackageManager().getPackageInfo( getPackageName(), PacakgeManager.GET_SIGNATURES );

for( Signature signature : packgeInfo.signatures ){

MessageDigest md = MessageDigest.getInstance( "SHA-256 ");

md.update( signature.toByteArray() );

key = new SecretKeySpec( md.digest(), "AES" );

break;

}

Cipher cipher = Cipher.getInstance( "AES" );

cipher.init( Cipher.ENCRYPT_MODE, key );

encryptedByte = cipher.doFinal( encryptByte ); // encryptByte 는 encrypt 하고자 하는 string 의 byte!!

String encryptedKeyStr = new String( Base64.encodeToString( encryptedByte, Base64.DEFAULT ) );

// TODO do sth with encryptedKeyStr

} catch( Exception e ){

Log.e( TAG, "secret key generation", e );

}




debug 모드와 호환해서 쓰기


debug 모드와 릴리즈 모드 시 구분을 위해서 다음과 같은 if else 로 분기하면 좋다.

if ( Config.getSignedMode( context ) == Config.SIGNED_AS_DEVELOPMENT ) ){

// TODO debug key mode

} else{

// TODO release key mode

}




Decrypt ( Decoding )


try{

Cipher cipher = null;

byte[] encryptedByte = Base64.decode( encryptedKeyStr, Base64.DEFAULT );

cipher = Cipher.getInstance( "AES" );

cipher.init( Cipher.DECRYPT_MODE, getSecretKey() ); // secret key 는 위에서 생성하는 signkey 로부터 생성한 녀석과 같다. 

byte[] decryptedByte = cipher.doFinal( encryptedData );

return new String( decryptedByte, "UTF-8" );

} catch( Exception e ){

Log.e( TAG, "decrypt", e );

}






반응형

댓글