1. TrustyOS

데이터의 암복호화 및 서명검증을 진행할 때, 내부적으로 사용할 키값은 어디에 어떻게 저장할까? buildConfig로 저장하든, local.properties로 저장하든, string상수로 저장하든, 키 파일을 res폴더에 저장해서 조회해 사용하든 공통점이 있다. 모두 앱 디컴파일할 때, string형태로 보인다는 것이다. 하지만 앱 디컴파일을 시도해 string형태로 키값이 보이지 않더라도 키는 결국 메모리에 남게된다. 이로 인해 키의 디버깅이 가능하거나 메모리 덤핑 등의 작업으로 개인키가 해커에게 노출될 수 있다.

이를 방지하기 위해 google은 안드로이드 플랫폼 설계 시, 보안 관련 부분은 하드웨어적 설계를 다르게 한다. 그 설계의 시초는 바로 메인 프로세서의 가상화 기술(ex. ARM의 Trustzone)을 사용한 TEE(Trusty Execution Environment)환경이다. 하지만 가상화 기술이 아닌 하드웨어적으로, 물리적인 격리된 환경도 구축하는데, 이를 SE(Secure Element)라고 한다.

2. TEE(Trusty Execution Environment)

신뢰할 수 있는 실행환경이란 뜻을 담고 있다. 이는 메인 프로세서의 가상화 기술을 사용하여 보안 관련 연산을 위해 조성되었다. 또한 이 곳에서 진행되는 연산들은 그에 맞는 보안 메모리 영역과 저장소를 통해 프로세스를 만들며, 스케줄링하고, 데이터를 영구적으로 저장하기도 한다. 위 그림의 화살표를 보면 알겠지만, 메인 프로세서 내, TEE환경에서의 연산은 메인 메모리/저장소의 '보안 영역'과 상호작용하고 있음을 알 수 있다.


참고 : https://source.android.com/docs/security/features/trusty?hl=ko

하지만 한 가지 아쉬운 점이 존재한다. 보안 영역이 따로 존재하고, 그에 따른 TrustyOS가 존재한다 하더라도 물리적으로 격리되진 않았다는 점이다. 이를 보안할 수 있는 솔루션은 바로, StrongBox keymaster HAL을 구현한 SE칩셋 환경이다.

3. SE(Secure Element)

물리적으로 격리된 독립적인 칩셋을 보유하고 있으며, 내부적으로 고유한 프로세서/메모리/저장소 등을 가진다. 따라서 TEE환경보다 보안적으로 안전하다 볼 수 있으며, 안드로이드 공식 홈페이지 또한 그렇게 권장하고 있다.

SE를 통한 keymaster를 구현할 때, 내부 하드웨어 모듈에서 구현할 수 있는 해싱/암호화 구현 스펙도 아래와 같이 명시되어 있는데, 이는 내부 SE모듈 칩셋이 아래 스펙의 보안 기능을 가지고 있다고 이해하면 될듯 하다.


참고 : https://developer.android.com/privacy-and-security/keystore?hl=ko#HardwareSecurityModule

4. Android Kernel vs Trusty Kernel

하드웨어 관점으로 2가지로 분류할 수 있다. 하나는 Normal World라는 분류와 또 하나는 Secure World이다. Normal World의 경우, 보안적 타격이 없는 연산들이 진행되는 곳이다. 쉽게 말해 일반적인 어플리케이션이 돌아가는 곳이라 보면 된다. 하지만 Secure World의 경우, 보안적으로 중요한 연산을 처리해야 하는 공간을 말한다. 이는 앞서 소개한 TEE/SE환경을 의미한다. 즉 위 그림을 토대로 분류해보면 아래와 같이 분류가 가능하다.

  • Normal World : 일반적인 연산
  • Secure World : 보안이 중요한 연산
    • TEE(Trusted Execution Environment)
    • SE(Secure Element)

우선, TEE환경에서 진행되는 보안작업 관련 프로세서 연산들은 그에 맞는 보안 영역의 저장소 및 메모리와 작업을 진행한다. 따라서 그에 맞는 연산, 캐싱, 프로세스 생성, 스케줄링, 데이터 영구 저장 등의 작업이 진행된다. 위 빨간 화살표를 보면 쉽게 이해될거라 생각한다.

하지만 이러한 것이 가능한건, 어플리케이션 단의 요구사항을 받고 그에 맞는 작업을 진행시키기 위함이다. 이를 가능하게 하는 것이 OS내의 Kernel인데, TEE환경에 대응하는 것이 바로 Trusty Kernel이다.

이는 SE환경도 마찬가지이다. TEE환경의 경우, 메인 메모리/저장소를 함께 사용하고 구역을 나누어 사용하지만 SE는 그게 아닌 독립적인 공간에서 작업이 된다. 그 후, TEE처럼 Trusty Kernel에 바인딩된다.

TEE건 SE건 작업의 요청/응답을 위해 거쳐야 하는 곳이 keymaster HAL이다. 이는 디바이스의 TEE환경 또는 SE환경에 따라 달라지기도 한다. 하지만 어쨋든 동일한 인터페이스를 사용하여 Android Kernel에 Driver로 제공된다는 것이고, 이것이 바로 Android KeyStore에 제공된다는 것이다.

5. 보안상 이점?

앞단에서도 말했지만, AndroidKeyStore으로 보안 작업은 TEE/SE환경을 사용해 TrustyOS에서 진행된다고 했다. 이는 즉, AndroidOS가 아니라는 말이고, 일반적은 AndroidOS에서 실행되는 어플리케이션으론 키값을 조회할 수 없다는 것이다. 아, 물론 AndroidKeyStore를 사용한 키값 조회는 불가능하다. 따라서 메모리에 남지 않기에, 메모리 덤프 및 디버깅이 불가능한 것이다.

그럼에도 불구하고 해커가 앱을 탈취한다면 어떨까? 물론 이 경우엔, 해커가 AndroidKeyStore API를 호출해 데이터의 암복호화 및 서명검증이 가능하다. 하지만 이 또한 제한이 있는데, key를 사용한 보안 작업 사용 조건을 걸 수 있다. 앱 시스템에 존재하는 지문 인식/패턴/핀 인증이 끝나야만 키 사용이 가능하도록 설정할 수 있다. 또한 특정 해시 알고리즘 및 암복호화/서명검증 스펙 조건을 만족시킬 때에만 키 사용을 승인할 수도 있다는 것이다. 즉, 해커가 앱을 탈취해 AndroidKeyStore API를 호출해 사용할 수 있다 해도 이러한 제약조건을 통해 보안성을 높일 수 있다.

6. 마치며

요약하면 아래와 같다.

  • AndroidKeyStore에 사용되는 key는 물리적 하드웨어 내에 저장된다.
  • 이런 하드웨어는 크게 SE칩셋 환경과 TEE환경으로 나뉜다.
  • SE칩셋 환경의 경우, 내부적으로 프로세서/저장소/메모리 등을 보유하며 자체적인 보안작업이 가능하다.
  • TEE환경의 경우, 가상화 기술(ex. AMR Trustzone) 사용으로 cpu를 2개로 나눈다. 그 중 하나가 TEE환경을 의미한다.
  • TEE환경에서의 연산 작업은 메인 메모리/저장소와 상호작용한다. 하지만 메인 메모리/저장소 또한 가상화 기술을 통해 '보안 공간'을 따로 할당받는다.
  • TEE/SE환경의 상호작용은 TrustyOS의 Trusty Kernel로 귀결된다.
  • Trusty Kernel내, keymaster HAL의 구현체 및 인터페이스가 존재한다. 지원되는 디바이스 종류에 따라 keymaster HAL 구현체는 다르다.
  • keymaster HAL은 Android Kernel내, Trusty Driver를 통해 소통한다.
  • Trusty Driver는 AndroidKeyStore API와 소통하게 된다.
  • AndroidKeyStore API를 통해, 앱은 데이터 암복호화/서명검증이 가능하다.

참고

profile
불가능보다 가능함에 몰입할 수 있는 개발자가 되기 위해 노력합니다.

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN