키 만들기
테스트를 위해 openssl 을 이용해서 RSA 용 public/private key 를 한짝 만들자. 만드는 법은 아래 링크를 참고하자.이렇게 만들어진 key 2개(public/private) 를 android project 에 옮겨 놓자. 아래처럼 assets 라는 directory 에 넣었다.
참고로 주의할 점은 resource/raw 에 넣으면 안된다. 이유는 잘 모르지만, 제대로 동작하지 않았다. 아래 page 를 참고하면 된다.
KeyReader
소스는 아래를 참고 했다.- java - Load RSA public key from file - Stack Overflow : RSA key file 을 읽어드리는 방법
public key 와 private key 를 일
public class KeyReader { public static PublicKey getPublicKey(InputStream ins) throws Exception{ byte[] keyBytes = _toByteArray(ins); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePublic(spec); } public static PrivateKey getPrivateKey(InputStream ins) throws Exception{ byte[] keyBytes = _toByteArray(ins); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate(spec); } private static byte[] _toByteArray(InputStream input) throws IOException{ ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[8192]; while ((nRead = input.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); return buffer.toByteArray(); } }
Test Code
이제 asset 에서 key 를 읽어드리고, 이 key 를 이용해서 "mytest" 를 encrypt / decrypt 하는 code 를 보자.public key 로 encrypt 하고 , private key 로 decrypt 하는 code 이다. kotlin code 라도 이해하는데는 큰 무리가 없을 것 같아서 kotlin code 로 그냥 넣었다.
// kotlin code val assetManager = _activity.getAssets() val ins = assetManager.open("public_key") val pubKey = KeyReader.getPublicKey(ins) val cipher = Cipher.getInstance("RSA/ECB/NoPadding") cipher.init(Cipher.ENCRYPT_MODE, pubKey) val cipherData = cipher.doFinal("mytest".toByteArray()) val ins2 = assetManager.open("private_key") val prvKey = KeyReader.getPrivateKey(ins2) cipher.init(Cipher.DECRYPT_MODE, prvKey) val cipherData2 = cipher.doFinal(cipherData)
보안
- Security and Design | Android Developers : public key 등을 소스안에 포함시킬 때 hacking 등을 어렵게 하기 위해, concatenation, XOR 등을 이용하라고 한다.
- RSA maximum bytes to encrypt, comparison to AES in terms of security? - Information Security Stack Exchange : 보통 2048-bit 의 RSA 를 많이 쓰는데, data 의 최고 size 가 245bytes 라고 한다. 그래서 보통 symmetric key 를 RSA 로 encrypt 해서 교환하고, data 는 size 제한이 없는 symmetric encryption 을 사용한다고 한다.
- java - What is the most appropriate way to store user settings in Android application - Stack Overflow : SharedPreference 에 id/pw 를 저장하는 것에 대한 의견들
- security - How is the Gmail password stored in Android - and where? - Android Enthusiasts Stack Exchange : Gmail 에서 Auth Token 을 사용한다고 한다.
기타 자료
Decrypt 관련
Android 에서 RSA encryption 예제
- Save/Load Private and Public Key to/from a file - Java - Snipplr Social Snippet Repository
- RSA Encryption: Difference between Java and Android - Stack Overflow
- Android Encryption with the Android Cryptography API - Developer.com
- RSA Encryption Decryption in Android - Stack Overflow
댓글 없음:
댓글 쓰기