2016-08-08 5 views
0

Realm을 로컬 데이터베이스로 사용 중이며 암호화해야합니다. 나는 안드로이드 키 스토어를 사용하여 SecretKey를 저장하려고 시도하고 있는데, 키 스토어에 저장하는 것처럼 보이지만, SecretKey.getEncoded()를 사용할 때 항상 null을 반환한다. 코드는 다음과 같습니다.Android 키 저장소에서 SecretKey를 가져오고 영역 IO와 함께 사용

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
     keyStore.load(null); 
     Enumeration<String> aliases = keyStore.aliases(); 

     while(aliases.hasMoreElements()) { 
      Log.v("KEY ALIAS",aliases.nextElement()); 
     } 


     SecretKey keyStoreKey = (SecretKey) keyStore.getKey(ALIAS, null); 

     if(keyStoreKey == null) { 
      Log.v("NO KEY","USING NEW KEY"); 
      KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(ALIAS, 
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT); 
      KeyGenParameterSpec keySpec = builder 
        .setKeySize(512) 
        .setRandomizedEncryptionRequired(true) 
        .setUserAuthenticationRequired(true) 
        .setUserAuthenticationValidityDurationSeconds(5 * 60) 
        .build(); 

      KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1", "AndroidKeyStore"); 
      kg.init(keySpec); 
      keyStoreKey = kg.generateKey(); 

      keyStore.setEntry(ALIAS, 
        new KeyStore.SecretKeyEntry(keyStoreKey), 
        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
          .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 
          .build()); 
     } else { 
      Log.v("GOT KEY","USING OLD KEY"); 
     } 

     //THIS IS THE LINE THAT RETURNS NULL WHEN USING A KEY FROM KEYSTORE 
     byte[] key = keyStoreKey.getEncoded(); 

그런 다음 영역에 '키'배열을 사용합니다. 첫 번째 실행 (키를 만들 때)에서는 코드가 제대로 작동하지만 키 저장소에서 코드를 찾으면 키의 바이트를 가져올 때 null 만 반환합니다.

답변

1

의도적입니다. Android KeyStore는 저장 한 후에 키 자료를 노출하지 않으며 대신 KeyStore에게 사용자를 대신하여 작업을 수행하도록 요청할 수 있습니다.

한 가지 해결책은 이중 계층 키를 사용하는 것입니다. 다음과 같이 대략적으로 작동합니다.

  1. 영역을 잠금 해제하는 데 사용할 키 (keyA)를 생성합니다.
  2. 두 번째 무작위 키 (keyB)를 생성합니다.
  3. KeyStore에 keyB를 저장하십시오.
  4. keyB를 사용하여 keyA를 암호화하십시오. 이것은 이제 임의의 문자열 일 수 있습니다. 어디서나 저장할 수 있습니다.
  5. SharedPreferences에 keyA의 암호화 된 버전을 저장하십시오.
  6. 영역을 열 때 (KeyB를 사용하여) KeyStore의 SharedPreferences에서 암호화 된 키 A를 해독하고 영역에 지정합니다.

here (아직 진행중인 작업)을 시연하는 샘플 프로젝트 작업 중입니다.