Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DevFest Android in Korea 2024 - 안드로이드의 문단속 : 앱을...

Dabin Moon
September 30, 2024

DevFest Android in Korea 2024 - 안드로이드의 문단속 : 앱을 지키는 암호화 이야기

DevFest Android in Korea 2024에서 발표한 안드로이드의 문단속 : 앱을 지키는 암호화 이야기 Speaker Deck입니다.

https://festa.io/events/5968

Dabin Moon

September 30, 2024
Tweet

More Decks by Dabin Moon

Other Decks in Programming

Transcript

  1. (debuggable = false) 일반적인 상용 앱의 경우.. ADB 명령어 실행

    DeviceExplorer하지만 안심하기에는 이르다! 이처럼, debuggable = false인 앱의 데이터는 일반적인 경우엔 확인할 수 없다!
  2. https://github.com/scottyab/rootbeer 루팅 탐지로 해결할 수 있지 않을까..👀 • 루트비어(rootbeer)와 같은

    루팅 탐지 오픈소스 • 루팅 감지 코드 직접 구현 • 보안 솔루션에서 제공해주는 루팅 탐지 . . . VS “루팅 탐지 우회 기법”
  3. 이제는 더 이상 물러날 곳이 없다! 데이터 유출을 막을 수

    없다면, 최후의 보루 암호화를 통해 앱의 데이터를 보호하자!
  4. 들어가기 전에.. 원본 데이터 복원이 필요하지 않다면, 해시가 좋은 선택이

    될 수 있다. • 복호화를 통해 원본 데이터 복원 가능 • 복호화 할 수 없음. 따라서, 해시값에서 원본 데이터 복원 불가 양방향 통행 일방 통행 다시 원래대로 돌아갈 수 없어.. • 비밀번호, 전자서명, 전자투표 등 입력 값이 동일한 해시 값을 반환하는지 검증하는 무결성 검증에 주로 사용 (양방향)암호화 해시(단방향 암호화) • Key, IV 등의 값이 변하지 않았을때 입력값이 같다면 매번 동일하게 암호화가 이뤄짐(단 Key, IV 등의 값이 변하면 같은 입력값이라도 다르게 암호화) • 입력값이 같으면 해시 함수 적용시 매번 동일한 해시값 반환 이 키만 있다면 다시 돌아갈 수 있어.. (java.security.MessageDigest) (javax.crypto.Cipher)
  5. 직접 구현해보자!(물론 1부터 100까지 전부 다는 아니구요..) javax.crypto 활용 JCE(Java

    Cryptography Extension) 자바 프로그래밍 언어의 암호화를 위한 프레임워크. java.security API를 통해 구현되고, JDK 1.1에서 처음으로 소개되었음. Java 플랫폼에 출시된 표준 암호화 확장. JDK 1.4부터 JCA(Java Cryptography Architecture)와 함께 JDK에 번들로 제공. (1.4 이전에는 번들되지 않고 별개로 존재하는 제품이었음) • 대표적인 클래스 : Cipher, Key Generator 등 https://docs.oracle.com/javase/8/docs/technotes/g uides/security/crypto/CryptoSpec.html JCA(Java Cryptography Architecture) • 대표적인 클래스 : KeyStore, Message Digest 등
  6. 직접 구현해보자!(물론 1부터 100까지 전부 다는 아니구요..) javax.crypto 활용 JCE(Java

    Cryptography Extension) 자바 프로그래밍 언어의 암호화를 위한 프레임워크. java.security API를 통해 구현되고, JDK 1.1에서 처음으로 소개되었음. Java 플랫폼에 출시된 표준 암호화 확장. JDK 1.4부터 JCA(Java Cryptography Architecture)와 함께 JDK에 번들로 제공. (1.4 이전에는 번들되지 않고 별개로 존재하는 제품이었음) • 대표적인 클래스 : Cipher, Key Generator 등 https://docs.oracle.com/javase/8/docs/technotes/g uides/security/crypto/CryptoSpec.html JCA(Java Cryptography Architecture) • 대표적인 클래스 : KeyStore, Message Digest 등 따라서 JCE(javax.crypto)에서 제공하는 Cipher 사용 아직까지 코틀린에서 직접적으로 제공하는 Cryptography 라이브러리 부재. Cipher : 암/복호화 기능을 제공하는 클래스
  7. Cipher Cipher에서 지원하는 암호화 알고리즘 Q. 많아도 너무 많다.. 어떤

    것을 쓰면 좋을까? A. 사실 합당한 이유만 있다면, 어떤 알고리즘을 써도 상관없다. 성능, 보안강도, 지원되는 SDK 버전 등을 잘 파악해서 적절한 알고리즘을 사용하는 것이 중요!
  8. 알아두면 좋은 것 대칭 키 암호화 공개 키(비대칭 키) 암호화

    (상대평가입니다 오해 금물😂) • RSA, ECC 등 • AES, DES 등 구분 대칭 키 암호화 공개 키 암호화 Key 단일 SecretKey Public-Private Key 쌍 속도 빠름 느림 비용 낮음 높음 보안강도 낮음 높음
  9. 오라클 패딩 공격이란? AES/CBC/Padding방식의 경우 오라클 패딩 공격에 취약하다. https://en.wikipedia.org/wiki/Padding_oracle_attack

    https://learn.microsoft.com/en-us/dotnet/standard/security/vulnerabilities-cbc-mode • 해당 공격의 경우 키 값을 몰라도 암호화 데이터를 해독할 수 있다는 점에서 치명적임 나중에 설명하겠지만, AES 알고리즘의 경우 16바이트 블록을 기준으로 암호화를 적용해서, AES/CBC의 경우 암호화하려는 데이터가 16바이트 배수 크기가 아니면, Exception을 발생시킨다.(Padding 방식에서는 부족한 바이트만큼 패딩 값으로 채움) 여기서 잠깐! AES/CBC/NoPadding방식도 지원하지만.. 대표적인Padding 방식 ◦ PKCS5Padding ◦ PKCS7Padding • 패딩 검증을 통해 암호화 데이터에 존재하는 패딩을 제거하고 평문을 탈취하는 공격
  10. 오라클 패딩 공격이란? AES/CBC/Padding방식의 경우 오라클 패딩 공격에 취약하다. https://en.wikipedia.org/wiki/Padding_oracle_attack

    https://learn.microsoft.com/en-us/dotnet/standard/security/vulnerabilities-cbc-mode • 해당 공격의 경우 키 값을 몰라도 암호화 데이터를 해독할 수 있다는 점에서 치명적임 나중에 설명하겠지만, AES 알고리즘의 경우 16바이트 블록을 기준으로 암호화를 적용해서, AES/CBC의 경우 암호화하려는 데이터가 16바이트 배수 크기가 아니면, Exception을 발생시킨다.(Padding 방식에서는 부족한 바이트만큼 패딩 값으로 채움) 여기서 잠깐! AES/CBC/NoPadding방식도 지원하지만.. 대표적인Padding 방식 ◦ PKCS5Padding ◦ PKCS7Padding • 패딩 검증을 통해 암호화 데이터에 존재하는 패딩을 제거하고 평문을 탈취하는 공격 이러한 문제가 있어 또다른 추천 방식인 AES/GCM에 대해서만 소개하겠습니다!
  11. AES란? 고급 암호화 표준(Advanced Encryption Standard, AES) 128비트(==16바이트)의 블록 단위로

    암호화를 수행하는 대칭 키 암호화 알고리즘 SecretKey Size • 128 비트(16바이트) • 192 비트(24바이트) • 256 비트 지원(32바이트) AES-128, AES-256 등… suffix에 붙는 숫자는 키 값 사이즈를 의미 즉 AES-256은 256비트의 SecretKey를 사용하는 AES 알고리즘
  12. AES/GCM이란? 갈루와/카운터 모드(Galois/Counter Mode, GCM) • GMAC과 CTR이 결합된 암호화

    모드 • AEAD(authenticated encryption with associated data) 에 속함 ◦ 데이터의 기밀성(confident), 무결성(integrity)및 인증성 (authenticity)을 보장하는 암호화 형식
  13. GCM - TAG & IV TAG • GMAC 유효성 검증에

    사용되는 값 • 128, 120, 112, 104, 96, 64, 32 bit 크기 지원 • 첫 블록을 암호화할 때 사용되는 값 IV(Initial Vector)
  14. CBC VS GCM 암호화 데이터 Size 비교 “abcdefghijklmnop abcdefghijklmnop” 31Byte

    PlainText CBC/PKCS5Padding CBC/PKCS7Padding CBC/NoPadding GCM/NoPadding encrypt TAG Size + 원본 데이터 Size(31Byte) 16바이트 배수가 아닌 데이터 별도의 처리 없이 encrypt시 exception 32Byte 32Byte “abcdefghijklmnop abcdefghijklmnopq” 32Byte PlainText CBC/PKCS5Padding CBC/PKCS7Padding CBC/NoPadding GCM/NoPadding encrypt TAG Size + 원본 데이터 Size(32Byte) 64Byte 64Byte 32Byte TAG Size(최대 16Byte) 원본 데이터 Size GCM 방식의 경우 TAG Size를 제외하면, 원본 데이터 Size가 암호화 시에도 그대로 유지된다. (+ 원본 데이터가 꼭 16바이트 배수일 필요도 없다.) GCM Encrypted Data Size
  15. 직접 구현해보자!(물론 1부터 100까지 전부 다는 아니구요..) Cipher encrypt decrypt

    어때요 참 쉽죠? Cipher 객체를 초기화하고, 원하는 암호화/복호화 모드 및 암호화 알고리즘을 설정해주고, 암호화 복호화를 진행한다. + 24바이트 + 24바이트
  16. 라인 바이 라인으로 분석해보자 (1) Cipher 객체 반환 및 초기화

    (2) Cipher 객체의 모드 지정 • ENCRYPT_MODE : 암호화 모드 • DECRYPT_MODE : 복호화 모드 • WRAP_MODE : Key-Wrapping 모드 • UNWRAP_MODE : Key-Unwrapping 모드 (3) 암호화에 사용될 시크릿 키 지정 • SecretKeySpec - 대칭 키 암호화 • RSAKeyGenParameterSpec - 공개 키 암호화 • KeyGenerator, KeyPairGenerator 등에서 생성된 Key 구현체 (4) 암호화 알고리즘에 사용될 파라미터 정의 • AlgorithmParamterSpec 구현체 • 각 암호화 알고리즘마다 구현체 존재 (1) (2) (1) (3) (4) + 24바이트
  17. 라인 바이 라인으로 분석해보자 (5) doFinal • 암호화 또는 복호화를

    실행할 때 사용 • 데이터 저장시 깨짐 방지를 위해 Base64인코딩/디코딩 (5) (6) (6) Base64(선택)
  18. 개발시 고려하면 좋은 것 • IV, SecretKey를 여러 데이터에서 재사용

    할 경우, 보안 취약점이 발생할 수 있다. • IV, SecretKey를 최대한 숨기고 못 알아보게 만드는 것이 중요하다. • 데이터마다 고유한 IV, SecretKey를 사용해서 암호화하면 보안 강도가 높아진다. • 적용하려는 암호화 알고리즘에 취약점은 없는지 충분히 검토해서 사용한다.
  19. Android KeyStore 구현도 용이하고, 프로젝트 코드 내에서 직접 SecretKey를 관리하는

    것보다 보안 측면에서 이점이 큼 암호화에 사용되는 키를 안전하게 저장할 수 있는 저장소 • Extraction prevention(추출 차단) • Hardware security module(하드웨어 보안 모듈) • Key use authorizations(키 사용 승인) 보안 기능
  20. Android KeyStore 유의사항 1. Android 전용 KeyStore 확장 라이브러리인 android.security.keystore의

    경우 sdk23 이상에서만 지원 따라서 sdk23 미만의 경우 JCA(java.security)를 활용해 대응
  21. Android KeyStore 유의사항 2. Android6(sdk 23) 이전 버전의 소프트웨어 기반

    KeyStore의 경우 루팅 기기에서 KeyStore 데이터를 탈취 가능하다. 3. KeyStore를 활용해 암호화 Data Storage를 구현하는 경우, 데이터 백업 케이스에 유의해야함. https://developer.android.com/identity/data/backup 앱이 삭제되면, 앱에서 KeyStore에 저장했던 Key값들은 자동으로 제거된다. allowBackUp = “true”, dataExtractionRules, fullBackupContent 등 백업 정책에 의해, 앱 데이터가 백업 될 경우 이전에 사용했던 Key를 KeyStore에서 찾을 수 없어, 원본 데이터 복원이 불가능해질 수 있다.
  22. EncryptedSharedPreferences • 암호화된 파일을 생성하고 읽기 위한 클래스 • SharedPreferences를

    래핑해서 데이터 저장 이전에 암호화를 수행하는 SharedPreferences EncryptedFile • 모든 하위 키(EncryptedSharedPreferences의 Key - Value를 암호화 하는 키, EncrypteFile의 파일을 암호화 하는 키) 를 암호화하는 키. • Android KeyStore에 보관 androidx.security.crypto 시작은 창대했으나.. MasterKey Tink를 기반으로 구현됨
  23. • 다양한 플랫폼에서 사용할 수 있음 • Tink Java의 경우

    Cipher를 활용해 구현되어있음. • Tink를 활용해서 암호화 로직을 작성하는 것도 가능함! https://developers.google.com/tink Google의 오픈소스 암호화 라이브러리 Tink란?
  24. 공식 해결책..? • 마스터키 재생성 • DB 재생성 EncryptedSharedPreferences, EncryptedFile

    문서에 가보면.. 백업 룰을 이용해 EncryptedSharedPreferences, EncryptedFile를 모두 백업에서 제외하라고 한다 😓 그외에도 유저들이 찾아낸 해결책(?)으로 아래와 같은 방법이 있다. (피할 수 없으면 막아라..)
  25. • 기존에 androidx.security.crypto를 사용하고 있었는데, 당장 Migration이 어렵다면 androidx.security.crypto를 그대로

    사용하고 크래시 방어로직을 작성한다. • 그렇지 않다면, Cipher 객체를 활용해서 File이나, SharedPreferences의 암호화 로직을 직접 구현하는 것도 좋은 방법이 될 것이다. 개발시 고려하면 좋은 것
  26. Structured DataBase(SQLite, Room)에서는 어떻게 암호화를 처리하면 좋을까? 아쉽게도 DataBase의 경우

    구글에서 공식적으로 제공하는 Cryptography 라이브러리가 아직은 따로 없다.
  27. 대표적인 서드파티 SQLCipher https://www.zetetic.net/sqlcipher/ https://github.com/sqlcipher Zetetic 팀에서 제공하는 SQLite의 암호화

    Extension • 커뮤니티 버전의 경우 무료 오픈소스 • sqlcipher-android : 안드로이드를 위한 SQLCipher • hexdump를 찍었을때 일반 SQLite DB의 경우 평문 노출, SQLCipher DB의 경우 암호화 처리 • AES256/CBC 암호화 알고리즘 사용 (주의) • Room 지원 https://github.com/sqlcipher/sqlcipher-android
  28. 고려하면 좋은 것 • SQLCipher와 같은 서드 파티 라이브러리의 경우

    디버깅이 어렵고, 커스텀이 어렵다는 단점도 존재 Cipher 객체를 활용해서 Database의 암호화 로직을 직접 구현하는 것도 좋은 방법이 될 것이다.
  29. 그 외 다른 Data Storage들의 경우..(ex. DataStore) 구글에서 공식적으로 제공하는

    Cryptography 라이브러리가 따로 없는 상태이다. 따라서 직접 구현하거나 서드파티 라이브러리 사용.
  30. 번외 ) 메모리에 저장되는 평문의 경우 어떻게 하면 좋을까? •

    중요한 정보의 경우 메모리 상에 최대한 짧게 로드시킨다. • GC가 빠르게 작동할 수 있게 최대한 지역변수 형태로 관리한다. • 더이상 사용하지 않는 중요 정보의 경우 바로바로 정리한다. 아무리 암호화를 잘 적용해도, 메모리 상에 평문이 노출되는 시점이 존재할 것
  31. 개인정보의 종류 https://www.privacy.go.kr/ 개인정보포탈 개인정보란? 「개인정보 보호법」에서 정의하는 개인정보는 살아

    있는 개인에 관한 정보로 아래에 해당하는 정보를 말합니다. ① 성명, 주민등록번호 및 영상 등을 통하여 개인을 알아볼 수 있는 정보 ② 해당 정보만으로는 특정 개인을 알아볼 수 없더라도 다른 정보와 쉽게 결합하여 알아볼 수 있는 정보 ③ ①또는 ②를 가명처리함으로써 원래의 상태로 복원하기 위한 추가 정보의 사용, 결합 없이는 특정 개인을 알아볼 수 없는 정보(가명정보)
  32. 개인정보의 종류 https://www.privacy.go.kr/ 개인정보포탈 개인정보란? 「개인정보 보호법」에서 정의하는 개인정보는 살아

    있는 개인에 관한 정보로 아래에 해당하는 정보를 말합니다. ① 성명, 주민등록번호 및 영상 등을 통하여 개인을 알아볼 수 있는 정보 ② 해당 정보만으로는 특정 개인을 알아볼 수 없더라도 다른 정보와 쉽게 결합하여 알아볼 수 있는 정보 ③ ①또는 ②를 가명처리함으로써 원래의 상태로 복원하기 위한 추가 정보의 사용, 결합 없이는 특정 개인을 알아볼 수 없는 정보(가명정보) 개인 정보는 고정불변의 개념보다는 시대, 기술, 인식에 따라 확대되는 개념으로 봐야함. 따라서 민감도 기준을 보다 세밀하게 선정해서 데이터를 보호해야한다.
  33. Self 취약점 진단 https://developer.android.com/privacy-and-security/risks https://mas.owasp.org/MASVS/ OWASP MASVS (The Open Worldwide

    Application Security Project Mobile Application Security Verification Standard) • 모바일 앱 보안을 위한 표준 • MASVS Control Groups에 정의된 Critical Section을 기준으로 앱내 취약점을 점검 공식문서 Security | privacy-and-security 하위 문서 항목들을 기준으로 앱내 취약점을 점검해도 좋음. • OWASP MASVS Control Groups에 정의된 문제에 대한 전담 페이지 존재.
  34. 취약점 진단 툴 https://labs.withsecure.com/tools/drozer 동적 분석 툴 drozer 정적 분석

    툴 Qodana, sonarQube 등 (대다수의 정적 코드 분석 툴에서는 취약점 레포트를 제공해줌)