InvalidKeyException: неверный формат ключа при чтении закрытого ключа EC из файла PEM в Java - PullRequest
0 голосов
/ 01 июня 2018

Я пытаюсь создать объект с закрытым ключом из заданного файла .pem.Файл имеет следующую структуру:

-----BEGIN EC PRIVATE KEY-----
...............................
...............................
...............................
-----END EC PRIVATE KEY-----

Я пытаюсь создать объект закрытого ключа с этим кодом:

public static String getKeyFromFile(String filename) throws IOException {
    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int) f.length()];
    dis.readFully(keyBytes);
    dis.close();

    String key = new String(keyBytes);

    return key;
}

public static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, NoSuchProviderException {
    String privateKeyPEM = getKeyFromFile("MY_FILE.pem");

    privateKeyPEM = privateKeyPEM.replace("-----BEGIN EC PRIVATE KEY-----\n", "");
    privateKeyPEM = privateKeyPEM.replace("-----END EC PRIVATE KEY-----", "");
    privateKeyPEM = privateKeyPEM.replaceAll("\n", "");
    privateKeyPEM = privateKeyPEM.replaceAll(" ", "");

    byte[] privateKeyBytes = privateKeyPEM.getBytes();
    String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
    byte[] decodedString = Base64.getDecoder().decode(encodedString);

    EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(decodedString);
    KeyFactory kf = KeyFactory.getInstance("EC");
    PrivateKey privKey = kf.generatePrivate(privKeySpec);

    return privKey;

При запуске этого метода я получаю эту ошибку:

java.security.InvalidKeyException: invalid key format

Я могу хорошо разобрать текст и удалить ненужные символы, но я не могу создать объект с закрытым ключом.Я могу создать объект с открытым ключом из аналогичного файла .crt, используя очень похожие методы.Я хочу быть в состоянии сделать это исключительно в Java и без openssl.Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 01 июня 2018

Ваш код неправильно декодирует данные base64:

privateKeyPEM содержит строковые данные между BEGIN и END данными (которые закодированы в base64).

ВашКод выполняет следующие действия:

byte[] privateKeyBytes = privateKeyPEM.getBytes();
// privateKeyBytes now contains the base64 encoded key data

String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
// encoded String contains now the base64 encoded data of the base64 encoded key data

byte[] decodedString = Base64.getDecoder().decode(encodedString);
// decodedString is not the base64 encoded data of your key data

Почему вы кодируете базу данных64, а затем в следующей строке декодируете ее - оба шага вместе просто бесполезны.

Что вам действительно нужно, так это применитьbase64 декодирует один раз на privateKeyPEM:

byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);

Если декодирование base64 завершается неудачно, то ваши данные base64 являются недействительными - скорее всего, из-за содержащихся пробелов или \r.

...