안드로이드 모바일 앱에서 사용되는 금융 정보, 개인 정보, 인증 정보 등의 중요한 정보는 기밀성을 보장할 수 있는 표준 암호화 알고리즘을 사용해 암호화를 해야 한다.

하지만, 중요한 정보를 취약한 암호화 알고리즘, 고정적인 대칭키, 짧은 키, 유추하기 쉬운 키를 이용해 암호화를 하면 제 3자가 쉽게 해독이 가능하여 평문의 정보를 획득할 수 있다.

인시큐어뱅크 앱은 대칭키가 항상 고정적이고, 평문의 대칭키를 사용하고 있고, 모든 단말기에 동일한 대칭키를 이용해 암호화를 하므로 취약점이 발생한다.


안드로이드 암호화 구현 취약점

취약점 진단

인시큐어뱅크 앱의 내부 저장소에 저장된 mySharedPreferences.xml 파일을 로컬 PC로 복사한다. 파일을 열어보면 아이디는 Base64 인코딩 되어 있고, 비밀번호는 암호화되어 있다.

비밀번호가 어떤 종류의 암호화 알고리즘으로 암호화가 되어 있고, 암호화된 비밀번호를 해독이 가능한지 살펴본다.



사용자가 앱을 실행하면 LoginActivity.java의 onCreate() 메소드가 실행된다. onCreate() 메소드 내의 login_buttons 변수는 사용자가 앱에서 로그인 버튼(R.id.login_button)을 클릭했을 때 어떤 동작을 취할 것인지 정의한다.


만약, 사용자가 로그인 버튼을 클릭하면 performlogin()이 호출된다.



perfromlogin()이 호출되면 사용자가 입력한 아이디와 비밀번호를 DoLogin.class로 전달한다.


입력한 정보는 Username_Text, Password_Text 변수에 저장이 되고, 각 변수에 저장된 정보를 DoLogin.class의 passed_username, passed_password 변수로 전달한다.



DoLogin.class의 onCreate() 메소드가 실행되면 전달받은 passed_username, passed_password를 각 변수(username, password)에 저장하고 RequestTask()를 호출한다.



RequestTask()가 실행되면 postData(parms[0])이 호출된다.



postData()가 실행되면 로그인 성공 메시지와 함께 아이디, 비밀번호를 로그에 기록한다. 이후 saveCreds() 인자로 username, password를 지정하여 호출한다.



saveCreds()가 실행되면 아이디를 Base64로 인코딩하고, 비밀번호는 내부적으로 정의된 암호화 클래스를 이용하여 AES로 암호화를 한다.


인코딩된 아이디와 암호화된 비밀번호는 mySharedPreferences.xml 파일의 각 변수에 저장된다.



내부적으로 정의된 암호화 클래스(CryptoClass)는 비밀번호를 암호화 및 복호화를 담당하는 중요한 클래스이다. 해당 클래스를 자세히 분석하면 암호화된 비밀번호를 복호화하는데 필요한 중요한 정보를 얻을 수 있다.


초기화 벡터(IV, Initialization Vector)는 첫 블록을 암호화할 때 사용되는 값이다. 초기화 백터 값이 동일한 경우 출력 결과 값이 항상 동일하므로 암호화마다 다른 초기화 백터를 사용해야 한다.


ivBytes 변수에 항상 동일한 값의 초기화 백터 값을 저장하고 있다.



대칭키 암호(Symmetric-key cryptosystem)는 암호화 알고리즘의 한 종류로 암호화할 때의 키와 복호화할 때의 키가 동일하다.


암호화를 하는 측과 복호화하는 측이 동일한 키를 공유해야 하며, 외부에 노출되지 않도록 비밀 관리를 해야 하는 중요한 키이다.


소스코드를 고면 대칭키의 설명이 주석으로 표시하고 있고, key 변수에 대칭키를 저장하고 있다. 대칭키 길이는 key 변수에 저장된 길이(32)에 8을 곱한 값인 256 비트이다.



대칭키 기반 암호화 중 하나인 AES는 표준화된 암호화 알고리즘이다. 다양한 정보의 인코딩의 암호화가 가능하며 128, 192, 256 비트 길이로 처리가 된다.


128 비트는 마지막 라운드 함수를 포함한 10번의 라운드를 돌려서 암호화를 하고, 192 비트는 12번을 돌려서 암호화를 하고, 256 비트는 14번을 돌려서 암호화를 한다.


cipher 변수를 보면 AES 암호화, CBC 운용 모드를 사용하고 있는 것을 확인할 수 있다.



안드로이드 앱에서 중요한 정보를 암호화를 할 때 AES 단독으로 암호화를 하지 않고, 아스키코드 형태의 Base64 인코딩 + AES 암호화를 적용한다.


지금까지 확인한 정보를 조합해보면 사용자가 비밀번호를 입력하면 AES로 암호화 + Base64 인코딩을 적용하여 파일에 저장한다. 복호화는 역순으로 파일에 저장된 정보를 Base64 디코딩 + AES 복호화를 적용하여 평문의 패스워드를 얻는다.



온라인 Base64 인코딩 및 디코딩 사이트로 이동하여 하얀색 화면에 mySharedPreferences.xml 파일에 저장된 비밀번호를 삽입하여 디코딩된 데이터를 파일로 저장한다.


decode the data from a Base64 string (base64 decoding) : 체크

export to a binary file : 체크


Base64 Online decode and encode



온라인 AES 암호화 및 복호화 사이트로 이동하여 Base64 디코딩된 파일을 선택하고, 소스코드에서 확인한 암호화 종류, 암호화 모드, 대칭키, 초기화 백터를 입력하고Decrypt 버튼을 클릭하면 평문의 비밀번호를 얻을 수 있다.


Input type : File

File : Base64 디코딩된 파일
Function : 암호화 알고리즘인 AES
Mode : 암호화 모드로 CBC
Key : 대칭키
Init.vector : 초기화 백터 값

AES Symmetric Ciphers Online



이 사이트도 온라인 AES 암호화 및 복호화 사이트이다. 하지만, 암호화된 비밀번호, 대칭키, 암호화 비트 총 3개의 값만 입력하면 자동으로 복호화를 한다.

Base64 인코딩, 초기화 백터, 암호화 모드는 사용자가 수동으로 입력하는 것이 정석이지만 해당 사이트와 같이 내부적으로 기본으로 설정되어 있어 따로 값을 지정하지 않아도 자동으로 복호화가 된다.

AES encryption



대응 방안 및 검증

암호화 구현 취약점소스코드에 대칭기가 하드코딩되어 있고, 고정적인 대칭키를 사용하므로 앱을 설치해서 이용하는 사용자의 암호화된 정보는 항상 동일하다.


만약, 사용자의 비밀번호와 같은 중요한 정보가 동일한 대칭키를 사용하여 동일한 암호화가 생성된다면 제 3자에게 중요한 정보가 쉽게 유출될 수 있다.


이를 해결하려면 사용자를 식별할 수 있는 핸드폰 번호, 기기 번호 등의 정보를 조합하여 대칭키를 동적으로 생성하여 암호화 및 복호화를 하면 된다.


암호화 구현 취약점
대칭키를 하드코딩하여 적용하지 말고, 사용자를 식별할 수 있는 핸드폰 번호, 기기 번호 등의 정보를 조합하여 생성

▶ 안드로이드 컴포넌트 취약점 (Android Activity)

▶ 안드로이드 백업 취약점 (Android Backup)

▶ 안드로이드 메모리 노출 취약점 (메모리 덤프)

  • 카카오톡-공유
  • 네이버-블로그-공유
  • 네이버-밴드-공유
  • 페이스북-공유
  • 트위터-공유
  • 카카오스토리-공유