2014-09-25 8 views
8

Ich versuche, den Android Key Store Provider zu verwenden, der in Android 4.3 verfügbar wurde, um einen privaten Schlüssel sicher zu speichern und diesen privaten Schlüssel dann zum Verschlüsseln und Decodieren von Daten zu verwenden.So speichern Sie Schlüssel mit Android Key Store Provider

Ich denke, ich habe den richtigen Ansatz und Code für diese bisher implementiert, aber ich bin derzeit mit einem seltsamen Problem konfrontiert, das ich nicht herausfinden kann.

Ich habe eine Klasse namens KeyStorage, dass ich das Schlüsselpaar erstellen verwenden, laden Sie die Schlüsselspeicher und Abrufen des privaten Schlüssels, der Code für diese Klasse ist wie folgt:

public class KeyStorage { 

public static final String ANDROID_KEYSTORE = "AndroidKeyStore"; 
private KeyStore keyStore; 

public void loadKeyStore() { 
    try { 
     keyStore = KeyStore.getInstance(ANDROID_KEYSTORE); 
     keyStore.load(null); 
     Enumeration<String> aliases = keyStore.aliases(); 
     while(aliases.hasMoreElements()) 
      Log.e("E", "Aliases = " + aliases.nextElement()); 
    } catch (Exception e) { 
     // TODO: Handle this appropriately in your app 
     e.printStackTrace(); 
    } 
} 

public void generateNewKeyPair(String alias, Context context) 
     throws Exception { 

    Calendar start = Calendar.getInstance(); 
    Calendar end = Calendar.getInstance(); 
    // expires 1 year from today 
    end.add(1, Calendar.YEAR); 

    KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context) 
      .setAlias(alias) 
      .setSubject(new X500Principal("CN=" + alias)) 
      .setSerialNumber(BigInteger.TEN) 
      .setStartDate(start.getTime()) 
      .setEndDate(end.getTime()) 
      .build(); 

    // use the Android keystore 
    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", ANDROID_KEYSTORE); 
    gen.initialize(spec); 

    // generates the keypair 
    gen.generateKeyPair(); 
} 

public PrivateKey loadPrivteKey(String alias) throws Exception { 

    if (keyStore.isKeyEntry(alias)) { 
     Log.e("E", "Could not find key alias: " + alias); 
     return null; 
    } 

    KeyStore.Entry entry = keyStore.getEntry(EnhancedCredentialStore.KEY_ALIAS, null); 

    if (!(entry instanceof KeyStore.PrivateKeyEntry)) { 
     Log.e("E", " alias: " + alias + " is not a PrivateKey"); 
     return null; 
    } 

    return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); 
} 

Ich habe dann eine Klasse mit dem Namen CredentialStore, in dem ich versuche, das zu verwenden. Ich erstelle einen Alias ​​mit dem Namen "MySecureKey" und versuche, einen privaten Schlüssel darauf zu erstellen und zu speichern. Wie Sie sehen können, versuche ich das neue Schlüsselpaar basierend auf dem Alias ​​zu erstellen, lade den Schlüsselspeicher und schließlich den privaten Schlüssel. Es funktioniert jedoch nicht.

public class CredentialStore { 

public static final String KEY_ALIAS = "MySecureKey"; 

private KeyStorage KeyStorage; 

public CredentialStore(Activity context){ 

    keyStorage = new KeyStorage(); 
    try { 
     keyStorage.generateNewKeyPair(KEY_ALIAS, context); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    blueBirdKeyStorage.loadKeyStore(); 

    try { 
     keyStorage.loadPrivteKey(KEY_ALIAS); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

ich die Protokolle wie folgt:

Aliases = MySecureKey 
Could not find key alias: MySecureKey 

Also, wenn ich die Aliase in der loadKeyStore Methode überprüfen sieht es wie es ist, wie es zurück in das Protokoll kommt. Wenn ich jedoch versuche, es mit der loadKeyStore-Methode aufzurufen, bekomme ich das Protokoll, dass es den Schlüssel "MySecureKey" nicht finden kann.

Ich kann keinen Grund dafür finden und Recherchen online hat sich als unfruchtbar erwiesen, also habe ich mich gefragt, ob jemand eine Idee hat, was schief gehen könnte?

+4

1. Sie erzeugen KeyPair und nicht davon Gebrauch machen. Ihre generateNewKeyPair-Methode gibt nichts zurück. 2. Sie speichern nichts in KeyStore, um es später zu laden. Bitte beachten Sie ein Beispiel zu KeyStore-Nutzung. Es könnte Ihnen helfen http://developer.android.com/samples/BasicAndroidKeyStore/index.html –

+0

@AlexanderZhak obwohl die vielen Upvotes, Ihr Kommentar ist falsch: Schauen Sie sich die offizielle doc: https://developer.android.com/ training/articles/keystore.html # UserAuthentication So verwenden Sie den Android Keystore - Sie müssen den Schlüssel nicht explizit eingeben, wenn Sie die KeyFactory mit der Android Keystore-Instanz verwenden. – for3st

Antwort

1

Warum ist es blueBirdKeyStore in:

blueBirdKeyStorage.loadKeyStore(); 

Sollte es nicht sein:

keyStorage.loadKeyStore(); 

Außerdem haben Sie nicht den 'Alias' in Ihrem loadPrivateKey() verwendet:

KeyStore.Entry entry = keyStore.getEntry(EnhancedCredentialStore.KEY_ALIAS, null); 

Jetzt bin ich nicht sicher, aber sollten Sie nicht den "Alias" in diesem verwenden?

0

loadPrivateKey in Ihrer Klasse verwendet nicht den "Alias", um den Schlüssel abzurufen. Es benutzt die Konstante einer anderen Klasse, also bin ich mir nicht sicher, was Sie hier erwarten.

+0

Nein, es verwendet den richtigen Alias. – for3st

1

Ihre Methode zu überprüfen, ob Ihr Schlüssel vorhanden ist fehlerhaft:

if (keyStore.isKeyEntry(alias)) { 
    Log.e("E", "Could not find key alias: " + alias); 
    return null; 
} 

Nach dem javadoc .isKeyEntry() das folgende Verhalten

Gibt true zurück, wenn der Eintrag mit dem gegebenen Alias ​​identifiziert wurde erstellt hat durch ein Aufruf von setKeyEntry oder durch einen Aufruf von setEntry mit einem PrivateKeyEntry oder einem SecretKeyEntry erstellt.

aber Ihr Schlüssel wurde nicht durch setEntry() erstellt. Ich denke, wenn Sie nur den Schlüssel mit

KeyStore.Entry entry = ks.getEntry(alias, null); 

laden, wird es nicht null sein.

Here is a full example with simple methods on how to use the Android Keystore with pre-M and M Apis.

Verwandte Themen