Невозможно преобразовать.jks в.pkcs12: избыточный закрытый ключ

Обновление 30 декабря 2017 г. - 4:

Мне удалось распаковать .jks файл и извлечь ключ и сертификаты из него. Для этого я написал небольшую программу nodejs, вдохновленную signerbox2 проект с открытым исходным кодом, который использует .jks подписать данные. В частности, я использую jksreader Пакет npm, который существует только в течение нескольких дней!

Программа, которую я написал, выглядит так:

const fs = require('fs');
      jksreader = require('jksreader'),

      pathToFile = process.argv[2],
      password = process.argv[3],

      contents = fs.readFileSync(pathToFile),
      parsedContent = jksreader.parse(contents);

var   key = jksreader.decode(parsedContent.material[0].key, password);

fs.writeFileSync('key', key);

for (var i = 0; i < parsedContent.material[0].certs.length; i++) {
  var cert = parsedContent.material[0].certs[i];
  fs.writeFileSync('cert' + i, cert);
}

Эта программа вызывается так:

node index.js /path/tp/my_key.jks my_password

Вывод выглядит как набор файлов:

cert0
cert1
cert2
cert3
key

Сертификаты представлены в формате DER, и их можно прочитать следующим образом (обратите внимание на -engine dstu параметр):

openssl x509 -in cert2 -inform der -text -noout -engine dstu

Тем не менее, я не могу понять, как прочитать (или преобразовать в PEM) ключ. Я все еще работаю над этим. openssl asn1parse хорошо работает на файл ключа. Вот openssl asn1parse выход. Я не уверен, куда идти отсюда.

Обновление 28 декабря 2017 г. - 3:

Я установил http://keystore-explorer.org/. Он также не может извлечь секретный ключ. Это может показать немного больше информации, чем я смог получить с keytool, Единственная странная вещь здесь - это то, что есть две почти идентичные копии одного и того же сертификата, названного в честь моего имени (заглавными буквами)

Вот признак того, что запись соответствует стандарту DSTU-4145:

Обновление 28 декабря 2017 г. - 2:

Ключ, содержащийся в .jks следует или как-то связан с " схемой подписи ДСТУ-4145 " (алгоритм). Это государственный стандарт в Украине.

Я почти ничего не знаю о схемах подписи; Например, DSTU-4145 можно найти на странице спецификации BouncyCastle.

Может быть, мне как-то нужно установить алгоритмы DSTU-4145, чтобы keytool знает, как извлечь закрытый ключ?

Обновление 28 декабря 2017 г. - 1:

Делаем это в следующей версии Java на Ubuntu:

$ java -version
java version "1.7.0_151"
OpenJDK Runtime Environment (IcedTea 2.6.11) (7u151-2.6.11-2ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.151-b01, mixed mode)

Также не работает на следующей версии Java под macOS:

java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Я обеспечен .jks от официального органа.

Я хотел бы конвертировать .jks подать в .pkcs12 использовать его с openssl, чтобы на самом деле что-то подписать. Вместо этого я получаю ошибку.

Это то, что я делаю:

$ keytool -importkeystore \
        -srckeystore my_keystore.jks \
        -destkeystore my_keystore.pkcs12 \
        -deststoretype pkcs12

Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Enter key password for <my_key>
keytool error: java.security.UnrecoverableKeyException: excess private key

В то же время, однако, ключ может быть указан:

$ keytool -list -keystore my_key.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

my_key, Jan 18, 1970, PrivateKeyEntry,
Certificate fingerprint (SHA1): A1:B2:C3:D4:E5:F6:85:E4:2B:03:B9:68:FD:AE:9D:5B:24:CF:BF:FF

Что я делаю неправильно?

1 ответ

Решение

Хорошая работа по поиску этого JS. (FYI Stack делает только один @ за комментарий - к счастью, я видел это в недавно модифицированном.)

Из этого теперь мы можем видеть, что ваш приватный ключ имеет атрибуты в PKCS8 (легальная, но очень редко используемая функция), которую, как я вижу, стандартная JCE не поддерживает (есть комментарий в decode но не в parseKey). Похоже, что BouncyCastle делает - но bcprov не делает JKS.

Я предлагаю вам перейти к OpenSSL здесь, так как это то, что вы хотите закончить в любом случае. Вы можете определенно преобразовать файл сертификата из двоичного файла /DER в PEM с помощью:

 openssl x509 -in cert$i -inform der -out cert$i.pem -engine dstu 
 # or maybe pem$i or whatever names you find convenient

Я уверен, что вы можете преобразовать файл ключа в PEM с помощью:

 openssl pkey -in key -inform der -out key.pem -engine dstu
 # or whatever name
 # output defaults to unencrypted but your input is already unencrypted so no loss

но если это не сработает, вы можете сделать это вручную:

(echo "-----BEGIN PRIVATE KEY-----"; openssl base64 <key; echo "-----END PRIVATE KEY-----") >key.pem 

и тогда вы сможете кормить PEM-файлы openssl pkcs12 -export -engine dstu создать PKCS12.

В качестве альтернативы, поскольку предполагается, что Stackru предназначен для программирования, я думаю, он будет работать, если вы используете провайдера BC для чтения ключа и записи PKCS12, что-то вроде:

KeyFactory kf = KeyFactory.getInstance ("DSTU4145", "BC");
PrivateKey key = kf.generatePrivate (new PKCS8EncodedKeySpec (Files.readAllBytes("key")));
CertificateFactory cf = CertificateFactory.getInstance ("X.509", "BC");
// not sure we need the BC implementation for the certs, but can't hurt 
Certificate[] certs = new Certificate[4];
for( int i = 0; i < 4; i++ ){
  certs[i] = cf.generateCertificate (new FileInputStream ("cert"+i));
  // or "cert"+i+".pem" -- CertificateFactory can read either DER or PEM
}
// or concatenate the cert PEM files into one and do
Certificate[] certs = cf.generateCertificates (new FileInputStream ("certs.pem")).toArray(new Certificate[0]);
// better to close the stream(s) when done like below but for input isn't vital

KeyStore ks = KeyStore.getInstance ("PKCS12", "BC"); ks.load(null); 
char[] pw = "password".toCharArray(); // or preferably better value
ks.setKeyEntry("mykey", pkey, pw, certs);
try(OutputStream os = new FileOutputStream("result")){ ks.store(os, pw); }
Другие вопросы по тегам