Я пытаюсь использовать поставщика хранилища ключей Android, который стал доступен в Android 4.3, для безопасного сохранения закрытого ключа, а затем использовать этот закрытый ключ для шифрования и декодирования данных.
Я думаю, что до сих пор реализовал правильный подход и код для этого, однако в настоящее время я сталкиваюсь со странной проблемой, которую не могу понять.
У меня есть класс под названием KeyStorage, который я использую для создания пары ключей, загрузки KeyStore и получения закрытого ключа, код для этого класса выглядит следующим образом:
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();
}
Затем у меня есть класс CredentialStore, в котором я пытаюсь использовать это. Я создаю псевдоним с именем «MySecureKey» и пытаюсь создать и сохранить закрытый ключ на его основе. Итак, как вы можете видеть, я пытаюсь создать новую пару ключей на основе псевдонима, загрузить хранилище ключей, а затем, наконец, получить закрытый ключ. Однако это не работает.
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();
}
}
Я получаю журналы следующим образом:
Aliases = MySecureKey
Could not find key alias: MySecureKey
Поэтому, когда я проверяю псевдонимы в методе loadKeyStore, похоже, что они есть, поскольку они возвращаются в журнал. Однако, когда я пытаюсь вызвать его с помощью метода loadKeyStore, я получаю журнал, в котором говорится, что он не может найти ключ «MySecureKey».
Я не могу найти причину этого, и поиск в Интернете оказался безрезультатным, поэтому мне было интересно, есть ли у кого-нибудь идеи, что может пойти не так?