diff --git a/008. KeyStore System and Security/img/0a705587-5f56-1dda-815f-7b7e972e77cd.png b/008. KeyStore System and Security/img/0a705587-5f56-1dda-815f-7b7e972e77cd.png new file mode 100644 index 0000000..c637926 Binary files /dev/null and b/008. KeyStore System and Security/img/0a705587-5f56-1dda-815f-7b7e972e77cd.png differ diff --git a/008. KeyStore System and Security/img/0a7056be-5f56-1b2b-815f-9ad40cf930c3.png b/008. KeyStore System and Security/img/0a7056be-5f56-1b2b-815f-9ad40cf930c3.png new file mode 100644 index 0000000..6b4792f Binary files /dev/null and b/008. KeyStore System and Security/img/0a7056be-5f56-1b2b-815f-9ad40cf930c3.png differ diff --git a/008. KeyStore System and Security/namhoonkim_01.md b/008. KeyStore System and Security/namhoonkim_01.md new file mode 100644 index 0000000..2f9134d --- /dev/null +++ b/008. KeyStore System and Security/namhoonkim_01.md @@ -0,0 +1,123 @@ +# KeyStore System and Security Part 0 : Keyword List + +### Encrypt/Decrypt (암호화 / 복호화) + +암호학은 정보를 보호하기 위해서 언어학적 방법론과 수학적 방법론을 다루는 학문이다. + +이 암호학의 최종 목표가 바로 암호화이다. + +암호화를 통해 보호해야할 데이터(혹은 메시지)가 있다고 할때, 이를 **Plaintext(평문)** 이라고 한다. + +이 평문을 암호화 알고리즘을 이용해 변환한 것을 **Ciphertext(암호문)** 라고 한다. + +이때 평문을 암호문으로 변환화는 과정을 **Encryption(암호화)** 라고 하며, 반대로 암호문을 평문으로 변환하는 과정을 **Decryption(복호화)** 라고 한다. + +### Symmetric Key (대칭키) + +대칭키 암호는 다른 말로 **비밀키** 암호라고도 한다. + +대칭키 암호는 암호화와 복호화를 수행하는 키가 동일한 암호를 말한다. + +**Kerkhoffs's principle (커코프 원칙)** + +커코프 원칙이란 암호 시스템의 안정성은 암호화 알고리즘이 아니라 암호키의 비밀에만 의존해야한다는 법칙을 말한다. + +만약 여러 사람이 사용하는 시스템에서 대칭키를 사용한다면 모든 사람은 같은 알고리즘을 쓰고 있을 것이고, 비밀성을 유지하는 것이 어려워지므로, 암호화 알고리즘의 비밀성이 주는 안정성은 의미가 없어진다. + +따라서 암호 시스템의 안정성은 알고리즘이 아닌 키의 비밀성에 의존해야 한다. + +#### Block Cipher + +대칭키를 이용한 암호화 방법 중 **Block cipher(블록 암호)** 라는 개념이 존재한다. + +이는 암호문을 생성하기 위해 암호화에 사용되는 키와 알고리즘이 데이터 블록 단위로 적용되는 방식이다. + +이러한 방식을 사용하는 이유는 평문을 일정한 길이의 블록으로 분할하여 전치와 치환을 반복함으로서 키에 대한 정보를 유추할 수 없도록 하는 데 있다. + +#### 대칭키 암호의 종류 +**DES : Data Encryption Standard** +- 64-bit 단위의 블록 암호로 56-bit 길이의 대칭키를 사용한다. +- 한때 미국 표준 블록 암호 알고리즘이었으나, 안정성에 문제가 있어 AES로 표준이 교체되었다. +- 현재 신규 암호화를 진행할때에는 **절대로 사용해서는 안되는 알고리즘** 이다. + +**AES : Advanced Encryption Standard** +- 현재 미국 표준 블록 암호 알고리즘이다. +- 가장 유명한 알고리즘으로 당연하겠지만 가장 긴 블록 길이인 AES-256이 권장된다. + +### Hash(해시) + +해시 함수는 임의의 크기를 가진 데이텉 입력 받아 고정된 크기의 결과값을 출력하는 함수이다. + +해시는 암호학뿐만 아니라 여러 분야에서 사용되며, **단방향성** 이라는 특성과 **충돌** 이라는 특성이 있다. + +단방향성이란 입력값으로 결과값을 계산하기는 쉽지만, 결과값을 가지고 입력값을 유추하기 어려운 특성을 말한다. + +즉 원문 메시지로 해시값을 생성하는 것은 쉽지만, 해시값을 통해 원문 메시지를 유추하는 것은 어렵다. + +충돌이란, 입력값이 다르더라도 동일한 결과값이 생성될 수 있는 특성을 말한다. + +해시 자체가 고정된 크기의 결과값을 출력해주기때문에, 표현할 수 있는 값이 한정되어있기때문에 발생하는 것이다. + +#### MessageDigest + +흔히 줄여서 MD라고도 하며, MD5 알고리즘이 가장 유명하다. + +다만 MD5도 취약점이 있으므로 최소 SHA-256을 쓰는 것이 권장된다. + +#### Checksum (체크섬) + +해시 함수는 일반적으로 데이터의 체크섬을 생성하기 위해서 사용한다. + +이 체크섬은 내려받은 파일이 정상인지 아닌지 판단하기 위하여 사용한다. + +### MAC : Message Authentication Code(메시지 인증 코드) + +메시지 인증 코드는 말 그대로 메시지를 인증할 때 쓰이는 값을 말한다. + +MAC값을 이용해 메시지의 데이터에 대한 인증을 물론 무결성을 증명한다. + +다만, MAC을 중간자가 탈취하는 경우 메시지를 변조하고 이를 통해 새로운 MAC을 만들어 보낼 수도 있기에 취약점이 존재한다. + +이를 방지하기 위해 다양한 MAC들이 존재한다. + +#### CMAC :Cipher-based Message Authentication Code + +CMAC은 메시지를 암호화하는 과정에서 주어진 값을 MAC으로 사용한다. + +다만, 메시지에 대한 암호화를 무조건 수행해야 한다는 단점이 있다. + +#### HMAC : Hash-based Authentication Function + +HMAC은 메시지에 대한 암호화없이 MAC을 얻는 방법 중 하나이다. + +키와 메시지를 합친 뒤 해시하여 얻어지는 값을 MAC으로 사용하는 방법인데, 이 또한 데이터를 주고 받는 양쪽에 사전 공유된 비밀키가 있어야 한다. + +### Asymmetric Key (비대칭키) + +비대칭키 암호화는 대칭키 암호화과 달리 키가 한 쌍이다. + +이 키는 **Public Key(공개키)** 와 **Private Key(개인키)** 로 구분되며 이를 이용한 암호화를 비대칭키 암호화 혹은 공개키 암호화라고 한다. + +비대칭키 암호화 또한 취약점이 없는 것은 아니나, 계산 복잡도에 매우 많은 시간을 요구하게끔 만들어졌으며 같은 키를 공유하는 대칭키 암호화에 비해 키 관리가 상대적으로 편하다는 장점이 있다. + +데이터를 공개키로 암호화하고, 암호화된 메시지는 개인키로 복호화하는 방식으므로 복호화를 위해선 무조건 개인키를 가지고 있어야 한다. + +**Diffie-Hallman key exchange** + +디피헬먼 키 교환은 비대칭키 암호화의 키를 교환하는 방법을 뜻한다. + +이산대수 연산을 기반으로 송신자와 수신자간의 비밀키를 공유하며, 지수 키 교환이라고도 불린다. + +#### RSA : Ronald-Shamir-Adleman + +세계적으로 가장 많이 쓰이는 공개키 암호화 방식이다. + +큰 정수를 소인수 분해하기 어렵다는 수학적 법칙하에 만들어진 알고리즘이지만, 수학적 구조 안에 존재하는 알고리즘의 태생상 많은 유형의 공격이 가능하기때문에 이를 방어하기 위해 인코딩을 하거나, 암호화 스킴등의 기법이 추가로 요구 된다. + +#### ECC : Elliptic Curves Cryptography + +타원 곡선 알고리즘 기반의 공개키 암호화 방식이다. + +평면 상의 주어진 특정한 점에 대한 무작위 타원 곡선의 이산 로그를 찾는 데 많은 시간이 소요됨을 이용해 만들어졌다. + +RSA보다 짧은 키를 가지고 구현이 가능하지만, 배경 지식이 어느 정도 요구되고 구현하기가 어렵다는 단점이 존재한다. \ No newline at end of file diff --git a/008. KeyStore System and Security/namhoonkim_02.md b/008. KeyStore System and Security/namhoonkim_02.md new file mode 100644 index 0000000..edfd04d --- /dev/null +++ b/008. KeyStore System and Security/namhoonkim_02.md @@ -0,0 +1,42 @@ +# Part 1 : What is KeyStore System? +- KeyStore 소개 및 동작 원리 +- Tusted Executon Environment + +### Android KeyStore Diagram + +![Android KeyStore Diagram](./img/0a705587-5f56-1dda-815f-7b7e972e77cd.png) + +### Android KeyStore의 보안 + +Android KeyStore에 저장되는 key들의 구성요소는 아래와 같은 수단으로 보호된다. + +1. Application 프로세스 레벨에서 Key Material의 접근은 전면 차단되며, System Process를 통해서만 siging등의 작업을 진행할 수 있다. +2. Plaintext, Cipher, message 등은 System Process를 통해서만 접근하여 받을 수 있다. + +### Hardware 기반의 KeyStore + +Android의 KeyStore는 필수적으로 하드웨어 기반으로만 구현된다. + +하드웨어를 통한 보안 기능은 ARM TrustZone을 통해 진행되며, RSA, ECDSA, AES, HMAC Key들은 전부 하드웨어 기반의 TrustZone에 저장된다. + +개발자는 TrustZone에 관련된 API를 사용하여 현재 Key가 신뢰할만한 하드웨어 장치에 저장되어있는 지 확인할 수 있으며, 지문 인증과 같은 사용자 본인의 인증없이는 특정 데이터를 Decrypt할 수 없게 구현할 수 있다. + +### TEE + +![TEE](./img/0a7056be-5f56-1b2b-815f-9ad40cf930c3.png) + +Android의 Key는 **TEE**(Tusted Executon Environment : 신뢰할 수 있는 실행환경)에서 바인딩되어 있으며 바인딩되어 있는 상태의 Key는 보안처리된 하드웨어 밖으로 절대 추출되지 않는다. + +이 TEE는 디바이스의 메인 프로세서에 따로 할당되어 있는 영역으로 데이터의 무결성을 보장해주며, 보안 영역의 분리를 통해 해킹, 멀웨어, 루트 권한 접근으로부터 보호받을 수 있게 된다. + + +#### (1) 시간적 유효성 승인 + +GateKeeper/Fingerprint Daemon을 통해 생성한 AuthToken에 기록된 마지막 TimeStamp를 통해 시간적 유효성을 확인 후 승인한다. + +#### (2) 암호화/사용자 인증 승인 + +Hardware 레벨에서 검증할 수 있는 수단을 통해 암호화 및 사용자 인증을 승인 한다. + +* Android 7.0부터 모든 기기는 TrustZone을 탑재하며, 기기 자체에 해당 TrustZone에 접근할 수 있는 고유 Key를 지닌다. +* 위의 고유한 Key를 가지지 않으면 모든 접근은 차단된다. diff --git a/008. KeyStore System and Security/namhoonkim_03.md b/008. KeyStore System and Security/namhoonkim_03.md new file mode 100644 index 0000000..d0e998c --- /dev/null +++ b/008. KeyStore System and Security/namhoonkim_03.md @@ -0,0 +1,9 @@ +# KeyStore System and Security Part 2 : Android Securty Crypto + +### SharedPreferences + +### EncryptedSharedPreferences + +### DataStore + +### Google Tink Library diff --git a/008. KeyStore System and Security/namhoonkim_04.md b/008. KeyStore System and Security/namhoonkim_04.md new file mode 100644 index 0000000..3815042 --- /dev/null +++ b/008. KeyStore System and Security/namhoonkim_04.md @@ -0,0 +1,61 @@ +# KeyStore System and Security Part 3 : Hiding strings + +Android 앱을 개발하다보면 특정 key를 포함해서 배포하는 경우가 있다. + +APK 파일의 특성상 기본적인 압축해제부터 디컴파일까지, 다양한 수단으로 기기의 바이너리 코드에 접근할 수 있는데, + +이떄 포함된 key값이 노출될 우려가 있다. + +어떻게하면 key를 숨길 수 있을까? + +완벽한 보안은 없지만, 최선을 다해서 숨겨보자. + +### 1. Hide in the `strings.xml` + +제일 먼저 문자열을 보관하는 리소스 파일인 `strings.xml`에 숨겨보자. + +아래와 같은 파일 구조로 작성이 되는 경우로 볼 수 있는데 + +```xml + + value + +``` + +value의 일부를 알고 있는 경우, 디컴파일할 것도 없이 `grep` 명령어만 이용해도 추출할 수 있다. + +디컴파일을 하게 되는 경우 `strings.xml` 파일에 원형 그대로 노출된다. + +따라서 이 방법은 **패키징만 되어있을 뿐**, 보안 관점에서는 매우 나쁜 방법이다. + +> jadx 예시 추가 필요 + +### 2. Hide in the `*.kt` (or `*.java`) + +소스 코드에 숨긴다고 하여도 결국 리소스 파일과 똑같이 관리되고, 리터럴 문자열은 난독화 대상이 아니기 때문에 마찬가지로 `grep` 명령어로 추출이 가능하다. + +리터럴 문자열이 아닌 별도의 `ByteArray`로 문자를 쪼개서 저장하더라도 컴파일러의 최적화로 인해 이또한 추출이 가능하다. + +즉 1번과 2번 방법은 모두 보안에 신경 썼다고 말하기 어려운 방법이며, 바꾸어 말하면 + +숨겨야할 key(혹은 문자열)은 1번과 2번 방법으로 처리해선 안된다고도 해석할 수 있다. + +### 3. Hide in the `BuildConfig.java` + +`build.gradle`과 `gradle.properties`에 숨겨보는 건 어떨까? + +이 또한 컴파일 후 1번, 2번 케이스와 동일해지므로 쓰면 안되는 방법이다. + +### 4. Hide in the Proguard + +Proguard 혹은 R8의 난독화 기능을 믿고 소스코드에 숨겨보는 건 어떨까? + +key를 포함시켰다는 건, 어딘가에 해당 key를 사용하기 떄문일 것이다. + +즉, key를 사용하는 메서드나 클래스등은 난독화되더라도, 중요한 key의 값은 리터럴로 관리되어서 난독화되지 않는다. + +따라서 코드가 완전 공개된 것은 아닐지라도, 약간의 수고로움만 거친다면 역시 값을 찾을 수 있다. + +### 5. Hide using Base64 +### 6. Hide using JNI +### 7. Android KeyBox \ No newline at end of file diff --git a/readme.md b/readme.md index 0fbe7be..bed1f80 100644 --- a/readme.md +++ b/readme.md @@ -55,4 +55,4 @@ Android 개발자들이 실무도중 경험한 이슈들에 대해서 공부하 **7. MVVM vs MVI (gathering)** **8. KeyStore System and Security (~ing)** -- branch guide : `keystore/{NAME}` +- branch guide : `security/{NAME}`