2016-04-19 39 views
9

Uso un SecretKey per crittografare i dati riservati nella mia applicazione. Attualmente sto memorizzando la mia SecretKey nel formato codificato Base64 in DB o SharedPrefs che non è un posto sicuro dove archiviare Secret su un telefono rooted. Quindi, voglio spostare la mia SecretKey a Android KeyStore. Il problema che sto affrontando è quando provo this sample code da Google, si aspetta un PrivateKey al posto di SecretKey. Non riuscivo a trovare un modo per memorizzare la mia SecretKey in KeyStore e recuperarla per un uso successivo. Ho provato questo:Android: Memorizza SecretKey nel KeyStore

private static void writeSecretKeyToKeystore(SecretKey secretKey, Context context) { 
KeyStore keyStore = null; 
try { 
    keyStore = KeyStore.getInstance("AndroidKeyStore"); 
    keyStore.load(null); 
    KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey); 
    keyStore.setKeyEntry("Key", secretKeyEntry.getSecretKey().getEncoded(), null); 
} catch (KeyStoreException e) { 
    e.printStackTrace(); 
} catch (CertificateException e) { 
    e.printStackTrace(); 
} catch (NoSuchAlgorithmException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

Quando provo sopra il codice, viene generata un'eccezione Operation not supported because encoding is unknown.

Qualsiasi codice di esempio sarebbe di grande aiuto.

+0

provare quanto segue: keyStore.setEntry ("Chiave", secretKeyEntry, null); –

+0

Non verrà compilato, dicendo 'Wrong 2nd argument type. Trovato "SecretKeyEntry"; richiesto 'byte []' '. – Rajkiran

+0

Per favore cambia "setKeyEntry" in "setEntry". –

risposta

5

SBAGLIATO
java.security.KeyStore in grado di memorizzare entrambe le chiavi simmetriche e asimmetriche. Hai solo bisogno di istanziare KeyStore.SecretKeyEntry passarlo vostra chiave segreta nel costruttore e quindi utilizzare il metodo KeyStore # setEntry per salvarlo:

keyStore.setEntry(
    "key1", 
    new KeyStore.SecretKeyEntry(secretKey), 
    new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
      .setBlockMode(KeyProperties.BLOCK_MODE_GCM) 
      .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 
      .build()); 

Per ottenere di nuovo fuori uso:

SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null); 

UPDATE
Dopo alcune ricerche sono stato sorpreso di scoprire che AndroidKeyStore non supporta le chiavi simmetriche. (vedere la discussione: https://groups.google.com/forum/#!topic/android-developers/gbmIRKRbfq8)

+0

Non vedo alcun metodo su KeyStore che accetta l'oggetto SecretKeyEntry. Inoltre, la tua risposta menziona come ottenere l'ingresso, più di come impostare la voce. Si prega di verificare la mia domanda aggiornata. – Rajkiran

+0

entrambi i metodi (getEntry e setEntry) gestiscono l'interfaccia KeyStore.Entry (consultare: http://developer.android.com/reference/java/security/KeyStore.Entry.html). KeyStore.SecretKeyEntry implementa questa interfaccia, quindi è possibile utilizzarla ovunque sia previsto KeyStore.Entry. –

+1

Questo non funzionerà su API <23. Sto sviluppando un'applicazione che inizia con Lollipop. Uso questo codice keyStore.setEntry ("key1", new KeyStore.SecretKeyEntry (secretKey), new KeyStoreParameter.Builder (context) .setEncryptionRequired (true) .build()); ma non funzionerebbe. Invvertita la tua risposta però. – Rajkiran