Android에서 액세스 토큰과 비밀을 안전하게 저장하는 방법은 무엇입니까?


123

oAuth를 사용하여 Google에서 메일과 연락처를 가져 오겠습니다. 액세스 토큰과 암호를 얻기 위해 로그인 할 때마다 사용자에게 묻고 싶지 않습니다. 내가 이해 한 바에 따르면 데이터베이스 또는 SharedPreferences. 하지만 보안 측면이 약간 걱정됩니다. 나는 당신이 토큰을 암호화하고 해독 할 수 있다고 읽었지만 공격자가 당신의 apk와 클래스를 디 컴파일하고 암호화 키를 얻는 것은 쉽다.
이러한 토큰을 Android에 안전하게 저장하는 가장 좋은 방법은 무엇입니까?


1
소비자 키와 비밀을 어떻게 저장합니까 (하드 코딩은 보안되지 않음)? 나는 그들이 accesstoken과 비밀을 요청하기 위해 필요합니다 .. oauth를 사용하는 다른 기존 앱은 어떻게 그것을합니까? 흠 마침내 oauth를 사용하면 훨씬 더 많은 보안 문제를 처리해야합니다 .... 소비자 토큰 / 비밀을 안전하게 유지하고 액세스 토큰과 비밀을 유지해야합니다 .... 마침내 더 간단하지 않을까요? 사용자의 사용자 이름 / 비밀번호를 암호화하여 저장 하시겠습니까? ... 결국 후자가 더 좋지 않습니까? 난 그냥 여전히 OAuth를이 ... 더 볼 수 없습니다
yeahman

액세스 토큰을 저장하는 파일을 알려주시겠습니까? 나는 안드로이드에 새로운 오전과 내가 샘플을 실행하려 플러스 난 아무데도 [GoogleAuthUtil.getToken () 메소드.] 찾을 해달라고 app.But
Abhishek Kaushik이

답변:


117

공유 기본 설정 으로 저장합니다 . 기본적으로 비공개이며 다른 앱은 액세스 할 수 없습니다. 루팅 된 기기에서 사용자가 읽기를 시도하는 일부 앱에 대한 액세스를 명시 적으로 허용하면 앱이이를 사용할 수는 있지만 보호 할 수는 없습니다. 암호화와 관련하여 사용자에게 매번 암호 해독 암호를 입력하도록 요구하거나 (따라서 자격 증명 캐싱 목적을 무효화) 키를 파일에 저장하면 동일한 문제가 발생합니다.

실제 사용자 이름 암호 대신 토큰을 저장하면 몇 가지 이점이 있습니다.

  • 타사 앱은 비밀번호를 알 필요가 없으며 사용자는 비밀번호를 원래 사이트 (Facebook, Twitter, Gmail 등)로만 전송하도록 할 수 있습니다.
  • 누군가 토큰을 훔쳐도 암호를 볼 수 없습니다 (사용자가 다른 사이트에서도 사용할 수 있음).
  • 토큰은 일반적으로 수명이 있으며 특정 시간이 지나면 만료됩니다.
  • 토큰이 손상되었다고 의심되는 경우 토큰을 취소 할 수 있습니다.

1
답장을 위해 thx! 하지만 내 소비자 키가 손상되었는지 어떻게 알 수 있습니까? lol 그것은 말하기 어려울 것입니다 .. 액세스 토큰과 시크릿을 저장하는 것에 대해 ok, ok 나는 그것들을 sharedpreferences에 저장하고 그것들을 암호화하지만 소비자 키와 비밀은 어떻습니까? 나는 그것들을 sharedpreferences에 저장할 수 없습니다 (처음에는 sharedpreference에 저장하기 위해 코드에 소비자 키와 비밀을 명시 적으로 작성해야합니다) .. 무슨 뜻인지 이해하지 못합니다.
yeahman

2
디 컴파일 후 즉시 표시되지 않도록 (다소) 난독 화 된 방식으로 앱에 삽입하거나 키와 시크릿이있는 자체 인증 프록시 웹앱을 사용해야합니다. 앱에 넣는 것이 분명히 더 쉬우 며 누군가 앱을 크래킹 할 위험이 충분히 낮다고 생각되면 그 접근 방식을 취하십시오. BTW, 위의 사항은 사용자 암호에 대한 것입니다. 소비자 키 / 비밀이 손상되었다는 사실을 알게되면 해당 키도 취소 할 수 있습니다 (물론 앱이 손상됨).
Nikolay Elenkov 2012

1
@NikolayElenkov : '암호화에 관해서는 사용자에게 매번 암호 해독 암호를 입력하도록 요구하거나 (그러므로 자격 증명 캐싱 목적을 무효화) 파일에 키를 저장하면 동일한 문제가 발생합니다.'라고 썼습니다. . 크래커가 앱을 뒤집어 암호화 작동 방식을 파악하면 어떨까요? 당신의 방어가 무너질 수 있습니다. 네이티브 코드를 사용하여 이러한 정보 (토큰, 암호화 ...)를 저장하는 것이 모범 사례입니까?
anhldbk 2014

1
앱 데이터가 지워지면 새로 고침 토큰이 손실되며 사용자가 원하는 것이 아닐 수 있습니다.
rds

1
이것은 오늘날 더 이상 토큰을 저장하는 가장 좋은 방법이 아닙니다!
Rahul Rastogi

19

AccountManager에 저장할 수 있습니다 . 이 사람들에 따르면 모범 사례로 간주됩니다.

여기에 이미지 설명 입력

공식적인 정의는 다음과 같습니다.

이 클래스는 사용자 온라인 계정의 중앙 집중식 레지스트리에 대한 액세스를 제공합니다. 사용자는 계정 당 한 번씩 자격 증명 (사용자 이름 및 암호)을 입력하여 애플리케이션이 "원 클릭"승인으로 온라인 리소스에 액세스 할 수 있도록합니다.

AccountManager 사용 방법에 대한 자세한 가이드 :

그러나 결국 AccountManager는 토큰을 일반 텍스트로만 저장합니다. 따라서 AccountManager에 저장하기 전에 암호를 암호화하는 것이 좋습니다. AESCrypt 또는 AESCrypto 와 같은 다양한 암호화 라이브러리를 활용할 수 있습니다.

또 다른 옵션은 Conceal 라이브러리 를 사용하는 것 입니다. Facebook에서는 충분히 안전하고 AccountManager보다 훨씬 사용하기 쉽습니다. 다음은 Conceal을 사용하여 비밀 파일을 저장하는 코드 조각입니다.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);

2
은폐하는 좋은 팁. 사용하기 매우 쉽습니다. 그리고 많은 사용 사례에서.
lagos

링크를 통해 Conceal을 찾을 수 없습니다. 비활성화 될 수 있습니다
user1114

10

SharedPreferences 보안 위치 자체 가 아닙니다 . 루팅 된 장치에서 우리는 모든 응용 프로그램의 SharedPrefereces xml을 쉽게 읽고 수정할 수 있습니다. 따라서 토큰은 비교적 자주 만료되어야합니다. 그러나 토큰이 매시간 만료 되더라도 SharedPreferences에서 새로운 토큰을 훔칠 수 있습니다. Android KeyStore는 예를 들어 SharedPreferences 또는 데이터베이스에 저장하기 위해 토큰을 암호화하는 데 사용될 암호화 키의 장기 저장 및 검색에 사용해야합니다. 키는 애플리케이션의 프로세스 내에 저장되지 않으므로 손상 되기 가 더 어렵 습니다.

따라서 장소보다 더 관련성이있는 것은 암호화 방식으로 서명 된 단기 JWT 사용, Android KeyStore를 사용하여 암호화, 보안 프로토콜로 전송 등 자체 보안 방법입니다.


9
그럼 어디에 저장할 수 있을까요?
Milind Mevada 2018

2
  1. Android 스튜디오의 프로젝트 창에서 "Project Files"를 선택하고 프로젝트의 루트 디렉토리에 "keystore.properties"라는 새 파일을 만듭니다.

여기에 이미지 설명 입력

  1. "keystore.properties"파일을 열고 액세스 토큰과 시크릿을 파일에 저장하십시오.

여기에 이미지 설명 입력

  1. 이제 모듈의 build.gradle 파일 에서 읽기 액세스 토큰 및 시크릿을 로드 합니다. 그런 다음 코드에서 직접 액세스 할 수 있도록 액세스 토큰 및 시크릿에 대한 BuildConfig 변수를 정의해야합니다. 귀하의 build.gradle는 다음과 같이 보일 수 있습니다 :

    ... ... ... 
    
    android {
        compileSdkVersion 26
    
        // Load values from keystore.properties file
        def keystorePropertiesFile = rootProject.file("keystore.properties")
        def keystoreProperties = new Properties()
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
        defaultConfig {
            applicationId "com.yourdomain.appname"
            minSdkVersion 16
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            // Create BuildConfig variables
            buildConfigField "String", "ACCESS_TOKEN", keystoreProperties["ACCESS_TOKEN"]
            buildConfigField "String", "SECRET", keystoreProperties["SECRET"]
        }
    }
  2. 다음과 같이 코드에서 액세스 토큰 및 암호를 사용할 수 있습니다.

    String accessToken = BuildConfig.ACCESS_TOKEN;
    String secret = BuildConfig.SECRET;

이렇게하면 프로젝트 내부에 일반 텍스트로 액세스 토큰과 시크릿을 저장할 필요가 없습니다. 따라서 누군가가 APK를 디 컴파일하더라도 외부 파일에서로드 할 때 액세스 토큰과 시크릿을 가져 오지 않습니다.


1
하드 코딩 대신 속성 파일을 생성하는 데 차이가없는 것 같습니다.
Dzshean

런타임에 토큰을 작성하고 싶습니다. 앱을 열 때마다 토큰이 변경 될 수 있습니다.
Rehan Sarwar

1
API 액세스 토큰과 같은 일부 토큰을 저장하는 매우 좋은 방법입니다. 사용자 자격 증명을 저장하려면 NDK가 더 나은 방법입니다.
Eric

7
이것은 애플리케이션에 민감한 정보를 저장하는 방법이 아닙니다! 이 접근 방식을 사용하여 저장소에 데이터가 포함되어 있지 않더라도 (데이터는 빌드 프로세스에 주입 됨) 간단한 디 컴파일 후에 모두가 볼 수 있도록 토큰 / 비밀이 일반 텍스트로 포함 된 BuildConfig 파일을 생성합니다.
Hrafn

-1

두 가지 옵션에 따라 액세스 토큰을 보호 할 수 있습니다.

  1. 반전되지 않는 Android 키 저장소에 액세스 토큰을 저장하십시오.
  2. 토큰을 저장하는 일부 계산에 NDK 함수를 사용하고 되돌리기가 매우 어려운 C ++ 코드로 NDK를 사용합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.