2013-08-21 6 views
6

Я хочу сгенерировать закрытый ключ из строки (файл .pem) в Java.Как сгенерировать секретный ключ RSA из строки * pem в Java

private static final String test = "-----BEGIN RSA PRIVATE KEY-----\n" + 
     "MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" + 
// and so on 
     "-----END RSA PRIVATE KEY-----"; 

try { 
    String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); 
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 

    byte [] encoded = Base64.decode(privKeyPEM); 

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PrivateKey privKey = kf.generatePrivate(keySpec); 
} 
catch (Exception e) { 
    e.printStackTrace(); 
} 

Последняя строка (функция generatePrivate) бросает это исключение:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source) 
    at java.security.KeyFactory.generatePrivate(Unknown Source) 
    at Test.main(Test.java:52) 
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
    at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source) 
    at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source) 
    at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source) 
    ... 3 more 

Если изменить секретный ключ к значению из .der файла он работает правильно, но мне нужно, чтобы сформировать частный файл ключа из файла .pem.

Я приложил скриншот байтов, напечатанных как строка (один раз жестко закодированный с \ n и один раз жестко закодированный без \ n) и один раз из файла.

Bigger Image

Output

Странная вещь, что выход из файла отличается от выхода из строк.

Если я попытаюсь закодировать файл .der с Base64, результат будет отличаться от строки в файле .pem. Почему это так?

+0

Вы нашли ответ вообще? –

+0

@ SankarP nope не очень. – Niklas

+0

в порядке. Я нашел решение. Ключи, начинающиеся с «----- BEGIN RSA PRIVATE KEY», являются файлами, закодированными pkcs1. Эта кодировка pkcs1 не поддерживается Java, если вы не используете внешнюю библиотеку, такую ​​как BouncyCastle. Я столкнулся с тем же вопросом вчера и примерно через 8 часов нашел решение. Если вы закодируете закрытый ключ с помощью pkcs8, он начнется как «--- BEGIN PRIVATE KEY ---», который будет обрабатываться java. НТН. –

ответ

1

Вы говорите, что последняя строка бросает исключение, то есть

PrivateKey privKey = kf.generatePrivate(keySpec);

Выше работает линия на keyspecs быть установлен правильно, т.е.

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

Так актуальна проблема с закодированными байтами массив. Вы сделали System.out после byte [] encoded = Base64.decode(privKeyPEM); и посмотрели, что такое выход.

Я понимаю, что если сообщение находится в формате MIME, то после определенных символов оно добавляет комбинацию возврата каретки и новой строки, чтобы строки не были слишком длинными для системы электронной почты или где бы вы ее не использовали.

Окончательный тест String имеет некоторый '\ n' в исходном тексте, который вы используете. Вы же избавиться от другого текста в строке ниже

String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); 
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 

Но, обратите внимание на строку,

"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" + 
// and so on 
     "-----END RSA PRIVATE KEY-----"; 

может иметь некоторые более «\ п» влево, которые могут привести к некоторым нежелательным символов при вы создаете ключи. Попробуйте еще раз System.out и посмотрите, как выглядит массив закодированных байтов, а также перед тем, как проверить String privKeyPEM и посмотреть, не осталось ли в нем лишнего символа.

Надеюсь, что это hepls.

+1

Я загрузил вывод 'закодированного'. http://pastebin.com/YUsNdhgW. Я также изменил тест на чистую строку без '\ n', и она тоже не работала. – Niklas

+0

Я также загрузил скриншот с выходом в виде строки. – Niklas

+0

Декодирование Base64 игнорирует разрывы строк и обычно все пробелы. –

Смежные вопросы