Я хочу преобразовать закрытый ключ в строку, чтобы пользователь мог сохранить его в жестком состоянии.
я попытался преобразовать закрытый ключ с помощью Base64, но выдал ошибку, указывающую, что PrivateKey.getEncoded() имеет значение null
Итак, я попробовал до Base64 и снова получил null .
public String newKey() throws
NoSuchAlgorithmException,
NoSuchProviderException,
InvalidAlgorithmParameterException, KeyStoreException, CertificateEncodingException, UnrecoverableEntryException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, KEYSTORE);
KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec
.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_ECB)
.setEncryptionPaddings(PADDING)
.build();
keyPairGenerator.initialize(keyGenParameterSpec);
PrivateKey key = keyPairGenerator.generateKeyPair().getPrivate();
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,null);
String a = privateKeyEntryToString(entry,key);
// java.util.Base64.getDecoder().decode(entry)
// Log.d("tag",entry);
Log.d("tag", "done in new Key returning keypublic");
return a;
// return keyPairGenerator.generateKeyPair().getPublic();
}
private String privateKeyEntryToString(KeyStore.PrivateKeyEntry privateKeyEntry,PrivateKey key) throws CertificateEncodingException {
Certificate certificate = privateKeyEntry.getCertificate();
if (key.getEncoded().length == 0){ // but here we get exception that it is null.
return "its empty";
}
// Convert PrivateKey and Certificate to String
String privateKeyString = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
String certificateString = Base64.encodeToString(certificate.getEncoded(), Base64.DEFAULT);
// Combine both strings with a separator for later use
return privateKeyString + "-----BEGIN CERTIFICATE-----\n" + certificateString;
Трассировки стека :
FATAL EXCEPTION: main
Process: com.leo.nopasswordforyou, PID: 9525
java.lang.NullPointerException: Attempt to get length of null array
@PresidentJamesK.Polk вы можете получить закрытый ключ во время его создания. И этот вопрос не о том, как получить закрытый ключ из хранилища ключей. ключ анализируется иначе, чем Entry.
Я предположил, что используемое хранилище ключей — это хранилище ключей Android. Если это неверно, вам потребуется предоставить дополнительный код, показывающий, откуда берутся аргументы вашей функции privateKeyEntryToString(). Вы можете получить объект PrivateKey из этого хранилища ключей, но он не содержит конфиденциальной информации о закрытом ключе и getEncoded(), вызванный по нему, вернет null.
@PresidentJamesK.Polk Я отредактировал исходный вопрос. и добавлена функция PrivateKeyEntryToString
А какова ценность KEYSTORE в KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, KEYSTORE);?
Я не понял, что вы имеете в виду, но после того, как keyPairGenerator будет предложено сгенерировать, он сохраняет их в хранилище ключей и возвращает KeyPair открытого и закрытого ключей в KeyPair.
Android содержит несколько реализаций хранилища ключей, которые можно использовать через один и тот же API. Одним из них является AndroidKeystore, который не позволяет экспортировать ключ, а другие реализации просто сохраняют пароль ключа, защищенный в файле, поэтому вы можете делать с закрытым ключом все, что хотите. Поэтому нам нужно знать значение KEYSTORE.
окончательная строка KEYSTORE = "AndroidKeyStore"; ,final String ALGORITHM = "RSA";
Тогда все происходит именно так, как предполагал Джеймс. Вы используете аппаратное хранилище, которое защищает ключи. Вам не нужно их где-либо хранить, они уже сохранены в безопасном виде и защищены аппаратной мерой безопасности. getEndcoded для таких ключей никогда не подойдет.
@Роберт, дело в том, что я получаю закрытый ключ из keyPairGenerator.generateKeyPair(), значит ли это, что после создания пары ключей он сохраняет их в KeyPair и при появлении запроса на получение пересылает ключ хранилища ключей. например: keyPairGenerator.generateKeyPair().getPrivate();
Вы не читали то, что я пишу.
Итак, есть ли другой способ (кроме KeyStore), где я могу получить оба ключа, а позже, получив ключи, я могу поместить их в KeyStore. @PresidentJamesK.Polk, извини, я не понял, что ты сказал.
Если у кого-то были другие способы получить ключи, пожалуйста, напишите ответ на него, чтобы я мог отметить этот вопрос как ответ. Спасибо
Если вам нужен закрытый ключ, просто не используйте AndroidKeystore. Просто найдите в Stackoverflow, как сгенерировать ключ RSA на Java без Android. Способ Java также будет работать на Android.
дело в том, что я получаю закрытый ключ из keyPairGenerator.generateKeyPair(), значит ли это, что после генерации keyPair он сохраняет их в KeyPair и при появлении запроса на получение пересылает ключ хранилища ключей. например:
keyPairGenerator.generateKeyPair().getPrivate();
Я думаю, что именно в этом заключается заблуждение. Ключи генерируются в хранилище ключей Android, а не импортируются в него. А хранилище ключей Android защищает ценность закрытого ключа.
Если вы хотите создать ключи в программном обеспечении, вы можете просто попробовать полностью удалить неправильно названный аргумент KEYSTORE; по умолчанию поставщик Android не будет использоваться. И да, это немного странный API, возможно, вы не сможете просто установить его на null и остаться совместимым; вам также, возможно, придется удалить NoSuchProviderException из любого пункта catch, если вы это сделаете.
Хранилище ключей Android защищает закрытые ключи и не позволяет экспортировать их из защищенной среды.