PKCS # 12: исключение DerInputStream.getLength()

Я генерирую сертификат с помощью команды keytool:

keytool -genkeypair -alias myRSAKey -keyalg RSA -keysize 1024 -keystore test.p12 -storepass test -storetype pkcs12

Затем, если я попытаюсь загрузить его с помощью API безопасности java, после получения файла в виде байта []:

KeyStore ks = KeyStore.getInstance("PKCS12");
try{
   ks.load(new ByteArrayInputStream(data), "test".toCharArray())
} catch (Exception e){
   ...
}

Я получаю DerInputStream.getLength(): lengthTag = 127, слишком большое исключение.

Что не так?

Ответ 1

У меня была эта проблема, и я искал глубины Google и до сих пор не смог найти ответ. Спустя несколько дней, сражаясь с устаревшим кодом ужасного качества, я обнаружил причину этой ошибки.

KeyStore.load(InputStream is, String pass);

этот метод принимает InputStream, и если есть какие-либо проблемы с таким InputStream, это исключение возникает, некоторые проблемы, с которыми я столкнулся:

  • InputStream указывает на неправильный/пустой/только что созданный файл
  • InputStream уже открыт или что-то еще удерживает ресурс
  • InputStream уже использовался и читал, поэтому позиция следующего байта InputStream заканчивается

Последний был ответственным за мою проблему. Код создавал InputStream из сертификата и продолжал использовать его в двух вызовах KeyStore.load(), первый из них был успешным, второй всегда получал мне эту ошибку.

Ответ 2

Возможно, созданный вами сертификат имеет дополнительный символ в конце, который неверно истолкован как другой сертификат. Используйте одну или несколько пустых строк в конце.

Обратитесь: Анализ сертификатов Java

Ответ 3

Для других с аналогичной проблемой:

"keystore load: DerInputStream.getLength(): lengthTag=109, too big."

Для меня решение заключалось в том, чтобы удалить параметр: -storetype pkcs12 так как стандартный тип jks

Ответ 4

Укажите тип сертификата в коде например:

System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); 

Ответ 5

Моя проблема (lengthTag=109, too big) заключалась в том, что файл .p12 на самом деле имеет формат JKS, а не формат PKCS # 12. Кто-то переименовал расширение файла. Восстановление в правильном формате PKCS решило проблему.

java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
    at sun.security.util.DerInputStream.getLength(DerInputStream.java:599)
    at sun.security.util.DerValue.init(DerValue.java:365)
    at sun.security.util.DerValue.<init>(DerValue.java:320)
    at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1914)
    at java.security.KeyStore.load(KeyStore.java:1445)

Чтобы проверить формат файла безопасности, используйте KeyStore Explorer, чтобы открыть файл. Левая нижняя панель показывает фактический формат.

Ответ 6

Вы делаете что-то неправильно.
Я попробовал вашу команду, а затем просто загрузил p12.
Работает следующий код:

 FileInputStream fin = new FileInputStream("..\\test.p12");
 KeyStore ks = KeyStore.getInstance("PKCS12");
 ks.load(fin, "123456".toCharArray());
 System.out.println(ks.getCertificate("myrsakey"));

Мне было интересно, добавили ли вы команду, как вы получаете сообщение об ошибке с keytool, что пароль должен быть не менее 6 символов.
Вы не получили эту ошибку? Какую версию java вы используете?
Примечание. Если вам нужно создать сертификаты, вы также можете изучить этот инструмент.
http://sourceforge.net/projects/certhelper/

Ответ 7

У меня была такая же проблема.

Мое решение заключается в замене PKCS12 на jceks в строке ниже, потому что я, по-видимому, использовал неправильный тип.

KeyStore clientStore = KeyStore.getInstance("PKCS12");

Ответ 8

Это произошло со мной, потому что я скопировал и вставил файл .p12 локально на моем компьютере с Windows 10. .p12 не .p12 как/почему это проблема, но когда я клонирую проект с файлами .p12 и указываю на них свой код, файлы работают. Однако, копирование и вставка файлов в проводнике Windows в другое место на жестком диске вызывает эту ошибку !!!!

Ответ 9

Это произошло со мной в Android Studio после перехода на AndroidX и использования новой среды тестирования. Даже удаление существующего ~/.android/debug.keystore мне не удалось

Решение было восстановить его вручную (примите все вопросы как пустые и скажите "да" на последнем)

$ keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000

И скопируйте это

$ rm ~/.android/debug.keystore
$ cp debug.keystore ~/.android/debug.keystore