Java - как разблокировать секретный ключ PEM, защищенный парольной фразой - PullRequest
0 голосов
/ 01 июня 2019

У меня есть файл ключа PEM, защищенный парольной фразой, сгенерированный OpenSSL

openssl genrsa -aes128 -passout stdin -out testfile.pem

Я также сгенерировал файл открытого ключа, используя OpenSSL

openssl rsa -in testfile.pem -out testfile_pub.pub (propts for password)

Я хотел бы иметь возможность использовать этот закрытый ключ для подписания своих претензий и т. д., а затем отправлять запросы.Я пытаюсь понять (или, скорее, подтвердить свое понимание) следующее:

1) Мой закрытый ключ защищен паролем. Значит ли это, что никто не может сгенерировать открытый ключ, не разблокировав его сначала?то есть, где защита?

2) Если бы я читал этот зашифрованный файл PEM с закрытым ключом на Java, мне пришлось бы сделать что-то похожее на:

\\ 1. Read file as string \\ 2. Replace all boring bits e.g. begin/end/rsa/private/public/key/enc/-- \\ 3. decode using Base64 \\ 4. read as PKCS8 keyspec and generate PrivateKey object

но разве это не значит, что никто на самом деле не мешает мне читать спецификации ключей?Я думаю, что я пытаюсь сравнить с тем, как мы генерируем JKS ключей с дополнительным keypass / storepass.Но, может быть, я не должен сравнивать это.

Может ли кто-нибудь помочь мне понять?

Спасибо,

1 Ответ

1 голос
/ 02 июня 2019

openssl rsa -in testfile.pem -out testfile_pub.pub не экспортирует открытый ключ, он фактически экспортирует закрытый ключ в виде открытого текста (если вы указали правильный пароль).Чтобы экспортировать открытый ключ, используйте параметр -pubout.

Да, вам понадобится пароль для экспорта открытого ключа.

Чтобы импортировать закрытый ключ в Java, вам потребуется преобразовать его вPKCS8 сначала:

openssl pkcs8 -topk8 -in testfile.pem -inform pem -out testfile_pkcs8.pem -outform pem

Затем вы можете импортировать его в Java следующим образом:

String encrypted = new String(Files.readAllBytes(Paths.get("testfile_pkcs8.pem")));  
encrypted = encrypted.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "");  
encrypted = encrypted.replace("-----END ENCRYPTED PRIVATE KEY-----", "");  
EncryptedPrivateKeyInfo pkInfo = new EncryptedPrivateKeyInfo(Base64.decode(encrypted));  
PBEKeySpec keySpec = new PBEKeySpec("mypassword".toCharArray()); // password  
SecretKeyFactory pbeKeyFactory = SecretKeyFactory.getInstance(pkInfo.getAlgName());  
PKCS8EncodedKeySpec encodedKeySpec = pkInfo.getKeySpec(pbeKeyFactory.generateSecret(keySpec));  
KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
PrivateKey encryptedPrivateKey = keyFactory.generatePrivate(encodedKeySpec);  

Нет, это не значит, что кто-то может прочитать ключ, потому что вам все равно нужно предоставитьпароль.

...