lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Android KeyStore 시스템

Android KeyStore 시스템에서는 암호화 키를 컨테이너에 저장해야 하므로 이 키를 기기에서 추출해내기가 더 어렵습니다. 일단 키가 키스토어에 들어가면, 이 키는 주요 머티리얼을 내보낼 수 없는 암호화 작업에 사용될 수 있습니다. 이 시스템에서는 또한 키 사용 시기와 사용 방법을 제한하는 기능이 있습니다(예: 키 사용을 위해 사용자 인증 요구 또는 특정 암호화 모드에서만 사용하도록 키를 제한). 자세한 내용은 보안 기능 섹션을 참조하세요.

KeyStore 시스템은 KeyChain API에 의해 사용될 뿐만 아니라 Android 4.3(API 레벨 18)에 소개된 Android KeyStore 제공자 기능에 의해서도 사용됩니다. 이 문서에서는 Android KeyStore 제공자의 사용 시기와 사용 방법을 살펴봅니다.

보안 기능

Android KeyStore 시스템은 주요 머티리얼의 불법 사용을 막아줍니다. 첫째, Android KeyStore는 애플리케이션 프로세스와 Android 기기로부터 주요 머티리얼이 추출되는 것을 차단하는 방식으로 Android 기기 밖에서 주요 머티리얼의 불법 사용을 줄여줍니다. 둘째, Android KeyStore는 적법한 키 사용을 앱에서 지정하도록 만든 다음 앱의 프로세스 밖에서 이러한 제한을 적용하는 방식으로 Android 기기 상에서 주요 머티리얼의 불법 사용을 줄여줍니다.

추출 차단

Android KeyStore 키의 주요 머티리얼이 추출되는 것을 차단하기 위해 두 가지 보안 조치가 사용됩니다.
  • 주요 머티리얼은 절대로 애플리케이션 프로세스에 들어가지 않습니다. Android KeyStore 키를 사용하여 애플리케이션이 암호화 작업을 수행하는 경우, 배후에서 서명하거나 확인하려는 일반 텍스트, 암호 텍스트 및 메시지는 암호화 작업을 수행하는 시스템 프로세스로 들어갑니다. 앱의 프로세스가 손상된 경우, 공격자가 앱 키를 사용할 수는 있겠지만 이 키의 주요 머티리얼을 추출해낼 수는 없습니다(예: Android 기기 밖에서 사용하기 위해 추출).
  • 주요 머티리얼은 Android 기기의 보안 하드웨어(예: TEE(Trusted Execution Environment), SE(Secure Element))에 바인딩될 수도 있습니다. 키에 대해 이 기능이 활성화되면, 키의 주요 머티리얼이 절대로 보안 하드웨어 밖에 노출되지 않습니다. Android OS가 손상되거나 공격자가 기기의 내부 저장소를 읽을 수 있는 경우, 이 공격자는 Android 기기에 있는 모든 앱의 Android KeyStore 키를 사용할 수는 있겠지만, 기기에서 키를 추출해낼 수는 없습니다. 이 기능이 활성화되려면 기기의 보안 하드웨어가 특정 조합의 키 알고리즘, 차단 모드, 변환 방법 및 다이제스트를 지원해야 하며, 이를 통해 키 사용을 승인합니다. 키에 대해 이 기능이 활성화되는지 여부를 확인하려면, 해당 키에 대해 KeyInfo를 구하고 KeyInfo.isInsideSecurityHardware()의 반환 값을 검사합니다.

키 사용 승인

Android 기기에서 키의 불법 사용을 줄이기 위해, Android KeyStore는 키를 생성하거나 가져올 때 적법한 키 사용을 앱에서 지정하도록 만듭니다. 키를 생성하거나 가져온 후에는 그 승인을 변경할 수 없습니다. 그런 다음 이 키가 사용될 때마다 Android KeyStore에 의해 승인이 시행됩니다. 이 기능은 고급 보안 기능이며, 일반적으로 키 생성/가져오기 이후(이전이나 도중은 아님) 애플리케이션 프로세스의 손상이 불법 키 사용으로 이어져서는 안 된다는 요구사항이 있는 경우에만 유용합니다.

지원되는 키 사용 승인은 다음과 같은 범주로 구분됩니다.

  • 암호화: 키를 사용할 수 있는 승인된 키 알고리즘, 작업 또는 용도(암호화, 암호 해독, 서명, 확인), 변환 방법, 차단 모드 및 다이제스트
  • 시간적 유효성 간격: 키 사용이 승인되는 시간 간격
  • 사용자 인증: 최근에 사용자가 인증된 경우에만 키를 사용할 수 있습니다. 키 사용을 위해 사용자 인증 요구를 참조하세요.

추가적인 보안 조치로서, 주요 머티리얼이 보안 하드웨어 안에 있는 키의 경우(KeyInfo.isInsideSecurityHardware() 참조), Android 기기마다 다르지만 일부 키 승인은 보안 하드웨어에 의해 시행될 수도 있습니다. '암호화' 승인 및 '사용자 인증' 승인은 주로 보안 하드웨어에 의해 시행됩니다. '시간적 유효성 간격' 승인은 대개 보안 하드웨어에 의해 시행되지 않는데, 그 이유는 일반적으로 독립된 실시간 보안 클록이 없기 때문입니다.

키의 사용자 인증 승인이 보안 하드웨어에 의해 시행되는지 여부는 KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()를 사용하여 쿼리할 수 있습니다.

키체인 또는 Android KeyStore 제공자 중에 선택

시스템 범위의 자격 증명을 원하면 KeyChain API를 사용합니다. 앱이 KeyChain API를 통해 자격 증명 사용을 요청하는 경우, 사용자는 설치된 자격 증명 중에서 이 앱이 액세스할 수 있는 자격 증명을 시스템 제공 UI를 통해 선택합니다. 이렇게 하면 사용자 동의 하에 여러 앱이 동일한 자격 증명을 사용할 수 있습니다.

Android KeyStore 제공자를 사용하면 개별 앱이 혼자만 액세스할 수 있는 자격 증명을 저장할 수 있습니다. 이 방법을 사용하면 앱이 혼자만 사용할 수 있는 자격 증명을 관리할 수 있을 뿐만 아니라 KeyChain API가 시스템 범위의 자격 증명에 제공하는 것과 동일한 보안 이점을 누릴 수 있습니다. 이 방법은 자격 증명을 선택하기 위한 사용자 상호작용이 필요 없습니다.

Android KeyStore 제공자 사용

이 기능을 사용하려면, 표준 KeyStoreKeyPairGenerator 또는 KeyGenerator 클래스와 Android 4.3(API 레벨 18)에 소개된 AndroidKeyStore 제공자를 함께 사용합니다.

AndroidKeyStoreKeyStore.getInstance(type) 메서드와 사용하기 위해 KeyStore 유형으로 등록되며, KeyPairGenerator.getInstance(algorithm, provider)KeyGenerator.getInstance(algorithm, provider) 메서드와 사용하기 위해 제공자로 등록됩니다.

새 개인 키 생성

PrivateKey를 생성하려면 자체 서명 인증서가 갖게 될 초기 X.509 특성도 지정해야 합니다. KeyStore.setKeyEntry를 사용하면 나중에 이 인증서를 CA(인증 기관)가 서명한 인증서로 바꿀 수 있습니다.

키를 생성하려면 KeyPairGeneratorKeyPairGeneratorSpec을 함께 사용합니다.

/*
 * Generate a new EC key pair entry in the Android Keystore by
 * using the KeyPairGenerator API. The private key can only be
 * used for signing or verification and only with SHA-256 or
 * SHA-512 as the message digest.
 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(
        alias,
        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
        .setDigests(KeyProperties.DIGEST_SHA256,
            KeyProperties.DIGEST_SHA512)
        .build());

KeyPair kp = kpg.generateKeyPair();

새 비밀 키 생성

키를 생성하려면 KeyGeneratorKeyGenParameterSpec을 함께 사용합니다.

키스토어 항목 사용

AndroidKeyStore 제공자 사용은 모든 표준 KeyStore API에서 발생합니다.

항목 나열

aliases() 메서드를 호출하여 키스토어에 항목을 나열합니다.

/*
 * Load the Android KeyStore instance using the the
 * "AndroidKeyStore" provider to list out what entries are
 * currently stored.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
Enumeration<String> aliases = ks.aliases();

데이터 서명 및 확인

키스토어에서 KeyStore.Entry를 가져오고 sign()과 같은 Signature API를 사용하여 데이터에 서명합니다.

/*
 * Use a PrivateKey in the KeyStore to create a signature over
 * some data.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
    Log.w(TAG, "Not an instance of a PrivateKeyEntry");
    return null;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();

마찬가지로, verify(byte[]) 메서드를 사용하여 데이터를 확인합니다.

/*
 * Verify a signature previously made by a PrivateKey in our
 * KeyStore. This uses the X.509 certificate attached to our
 * private key in the KeyStore to validate a previously
 * generated signature.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
    Log.w(TAG, "Not an instance of a PrivateKeyEntry");
    return false;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initVerify(((PrivateKeyEntry) entry).getCertificate());
s.update(data);
boolean valid = s.verify(signature);

키 사용을 위해 사용자 인증 요구

키를 생성하거나 AndroidKeyStore로 가져올 경우, 사용자가 인증된 후에만 키 사용을 승인하도록 지정할 수 있습니다. 사용자는 자신의 보안 잠금 화면 자격 증명(패턴/PIN/암호, 지문)을 사용하여 인증됩니다.

이 기능은 고급 보안 기능이며, 일반적으로 키 생성/가져오기 이후(이전이나 도중은 아님) 애플리케이션 프로세스 손상이 키 사용을 위한 사용자 인증 요구사항을 무시해서는 안 된다는 요구사항이 있는 경우에만 유용합니다.

사용자가 인증된 후에만 키 사용을 승인하는 경우, 두 가지 모드 중 하나에서 작동하도록 구성할 수 있습니다.

  • 사용자 인증에서 일정한 기간 동안 키 사용을 승인합니다. 이 모드에서는 사용자가 보안 잠금 화면을 해제하거나 KeyguardManager.createConfirmDeviceCredentialIntent 흐름을 사용하여 보안 잠금 화면 자격 증명을 확인하는 즉시 모든 키의 사용이 승인됩니다. 승인이 유효하게 유지되는 기간은 각 키마다 다르며, 이 기간은 키 생성 또는 가져오기 중에 setUserAuthenticationValidityDurationSeconds를 사용하여 지정됩니다. 이러한 키는 보안 잠금 화면이 활성화된 경우에만 생성되거나 가져올 수 있습니다(KeyguardManager.isDeviceSecure() 참조). 보안 잠금 화면이 비활성화되면 이러한 키는 영구적으로 무효화되거나(사용자를 인증하지 않는 None 모드, Swipe 모드 또는 기타 모드로 재구성) 또는 강제로 재설정됩니다(예: 기기 관리자에 의해 재설정).
  • 사용자 인증에서는 하나의 키와 연관된 특정 암호화 작업을 승인합니다. 이 모드에서는 이러한 키가 관련된 각 작업을 사용자가 개별적으로 승인해야 합니다. 현재로서는 이러한 승인의 유일한 수단은 지문 인증(FingerprintManager.authenticate)뿐입니다. 이러한 키는 최소 하나 이상의 지문이 등록된 경우에만 생성되거나 가져올 수 있습니다(FingerprintManager.hasEnrolledFingerprints 참조). 지문이 새로 등록되거나 모든 지문이 등록 해제되면 이러한 키가 영구적으로 무효화됩니다.

지원되는 알고리즘

Cipher

알고리즘 지원 버전(API 레벨) 참고
AES/CBC/NoPadding 23+
AES/CBC/PKCS7Padding 23+
AES/CTR/NoPadding 23+
AES/ECB/NoPadding 23+
AES/ECB/PKCS7Padding 23+
AES/GCM/NoPadding 23+ 12바이트 길이 IV만 지원됩니다.
RSA/ECB/NoPadding 18+
RSA/ECB/PKCS1Padding 18+
RSA/ECB/OAEPWithSHA-1AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-224AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-256AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-384AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-512AndMGF1Padding 23+
RSA/ECB/OAEPPadding 23+

KeyGenerator

알고리즘 지원 버전(API 레벨) 참고
AES 23+ 지원되는 크기: 128, 192, 256
HmacSHA1 23+
  • 지원되는 크기: 8--1024(경계 숫자 포함), 8의 배수가 되어야 함
  • 기본 크기: 160
HmacSHA224 23+
  • 지원되는 크기: 8--1024(경계 숫자 포함), 8의 배수가 되어야 함
  • 기본 크기: 224
HmacSHA256 23+
  • 지원되는 크기: 8--1024(경계 숫자 포함), 8의 배수가 되어야 함
  • 기본 크기: 256
HmacSHA384 23+
  • 지원되는 크기: 8--1024(경계 숫자 포함), 8의 배수가 되어야 함
  • 기본 크기: 384
HmacSHA512 23+
  • 지원되는 크기: 8--1024(경계 숫자 포함), 8의 배수가 되어야 함
  • 기본 크기: 512

KeyFactory

알고리즘 지원 버전(API 레벨) 참고
EC 23+ 지원되는 키 사양: KeyInfo (개인 키 전용), ECPublicKeySpec (공개 키 전용), X509EncodedKeySpec (공개 키 전용)
RSA 23+ 지원되는 키 사양: KeyInfo (개인 키 전용), RSAPublicKeySpec (공개 키 전용), X509EncodedKeySpec (공개 키 전용)

KeyStore

KeyStore는 KeyPairGeneratorKeyGenerator와 동일한 키 유형을 지원합니다.

KeyPairGenerator

알고리즘 지원 버전(API 레벨) 참고
DSA 19–22
EC 23+
  • 지원되는 크기: 224, 256, 384, 521
  • 지원되는 명명된 곡선: P-224(secp224r1), P-256(secp256r1 및 prime256v1), P-384(secp384r1), P-521(secp521r1)

API 레벨 23 이전의 경우, "RSA" 알고리즘으로 초기화된 KeyPairGeneratorSpec의 KeyPairGenerator를 사용하여 EC 키를 생성할 수 있으며, 키 유형은 setKeyType(String)을 사용하여 "EC"로 설정됩니다. EC 곡선 이름은 이 방법을 사용하여 지정될 수 없으며, 요청된 키 크기에 따라 NIST P 곡선이 자동으로 선택됩니다.

RSA 18+
  • 지원되는 크기: 512, 768, 1024, 2048, 3072, 4096
  • 지원되는 공개 지수: 3, 65537
  • 기본 공개 지수: 65537

Mac

알고리즘 지원 버전(API 레벨) 참고
HmacSHA1 23+
HmacSHA224 23+
HmacSHA256 23+
HmacSHA384 23+
HmacSHA512 23+

Signature

알고리즘 지원 버전(API 레벨) 참고
MD5withRSA 18+
NONEwithECDSA 23+
NONEwithRSA 18+
SHA1withDSA 19–22
SHA1withECDSA 19+
SHA1withRSA 18+
SHA1withRSA/PSS 23+
SHA224withDSA 20–22
SHA224withECDSA 20+
SHA224withRSA 20+
SHA224withRSA/PSS 23+
SHA256withDSA 19–22
SHA256withECDSA 19+
SHA256withRSA 18+
SHA256withRSA/PSS 23+
SHA384withDSA 19–22
SHA384withECDSA 19+
SHA384withRSA 18+
SHA384withRSA/PSS 23+
SHA512withDSA 19–22
SHA512withECDSA 19+
SHA512withRSA 18+
SHA512withRSA/PSS 23+

SecretKeyFactory

알고리즘 지원 버전(API 레벨) 참고
AES 23+ 지원되는 키 사양: KeyInfo
HmacSHA1 23+ 지원되는 키 사양: KeyInfo
HmacSHA224 23+ 지원되는 키 사양: KeyInfo
HmacSHA256 23+ 지원되는 키 사양: KeyInfo
HmacSHA384 23+ 지원되는 키 사양: KeyInfo
HmacSHA512 23+ 지원되는 키 사양: KeyInfo