Java 11 — закрытый ключ эллиптической кривой — java.безопасность.Исключение InvalidKeyException: Исключение IOException : ввод DER, ошибка целочисленного тега

#java #encryption #elliptic-curve

#Ява #шифрование #эллиптическая кривая

Вопрос:

Небольшой вопрос о том, как использовать закрытый ключ эллиптической кривой с java 11, пожалуйста.

У меня есть эти команды:

 openssl pkcs12 -in file.p12 -out output.txt Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase:  

затем я могу запустить cat на выходе:

 cat output.txt Bag Attributes  friendlyName:   localKeyID:  Key Attributes: lt;No Attributesgt; -----BEGIN ENCRYPTED PRIVATE KEY----- MI[...]0= -----END ENCRYPTED PRIVATE KEY----- Bag Attributes  friendlyName:   localKeyID:  subject=/CN= issuer=/CN= -----BEGIN CERTIFICATE----- MII[...]Z -----END CERTIFICATE-----  

Обратите внимание, я использую […] для редактирования фактического содержимого.

И я просто хочу использовать этот закрытый ключ, тот, что в -----BEGIN ENCRYPTED PRIVATE KEY----- -----END ENCRYPTED PRIVATE KEY----- блоке

Поэтому я попробовал следующее: сначала я удалил ЗАШИФРОВАННЫЙ ЗАКРЫТЫЙ ключ BEGIN, разрывы строк, ЗАШИФРОВАННЫЙ ЗАКРЫТЫЙ КЛЮЧ END

 String privateKeyPEM = "MI[...]0="; //the same private key as above  byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);  EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);  KeyFactory kf = KeyFactory.getInstance("EC");  PrivateKey privKey = kf.generatePrivate(privKeySpec);  

Однако я получаю эту ошибку:

 aused by: java.security.InvalidKeyException: IOException : DER input, Integer tag error  at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350)  at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)  at jdk.crypto.ec/sun.security.ec.ECPrivateKeyImpl.lt;initgt;(ECPrivateKeyImpl.java:74)  at jdk.crypto.ec/sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)  at jdk.crypto.ec/sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)  

Могу я спросить, в чем, пожалуйста, проблема? Кроме того, могу я спросить, как это исправить?

Спасибо

Ответ №1:

Проблем нет, но ключ (EC), который вы пытаетесь прочитать, зашифрован — чистая Java не может считывать ключи такого рода.

Вы можете написать много кода для анализа и расшифровки ключа или использовать Надувной замок, чтобы выполнить эту работу за вас.

Добавьте эту строку в начало вашей программы:

 Security.addProvider(new BouncyCastleProvider());  

затем используйте эту функцию, где строка s принимает зашифрованный ключ, включая строки «— Begin — / end:

 static public PrivateKey stringToPrivateKey(String s, String password)  throws IOException, PKCSException {  PrivateKeyInfo pki;  try (PEMParser pemParser = new PEMParser(new StringReader(s))) {  Object o = pemParser.readObject();  if (o instanceof PKCS8EncryptedPrivateKeyInfo) { // encrypted private key in pkcs8-format  System.out.println("key in pkcs8 encoding");  PKCS8EncryptedPrivateKeyInfo epki = (PKCS8EncryptedPrivateKeyInfo) o;  System.out.println("epki:"   epki.getEncryptionAlgorithm().getAlgorithm());  JcePKCSPBEInputDecryptorProviderBuilder builder =  new JcePKCSPBEInputDecryptorProviderBuilder().setProvider("BC");  InputDecryptorProvider idp = builder.build(password.toCharArray());  pki = epki.decryptPrivateKeyInfo(idp);  } else if (o instanceof PEMEncryptedKeyPair) { // encrypted private key in pkcs8-format  System.out.println("key in pkcs1 encoding");  PEMEncryptedKeyPair epki = (PEMEncryptedKeyPair) o;  PEMKeyPair pkp = epki.decryptKeyPair(new BcPEMDecryptorProvider(password.toCharArray()));  pki = pkp.getPrivateKeyInfo();  } else if (o instanceof PEMKeyPair) { // unencrypted private key  System.out.println("key unencrypted");  PEMKeyPair pkp = (PEMKeyPair) o;  pki = pkp.getPrivateKeyInfo();  } else {  throw new PKCSException("Invalid encrypted private key class: "   o.getClass().getName());  }  JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");  return converter.getPrivateKey(pki);  } }  

Комментарии:

1. Действительно, большое спасибо @Michael!