Хранить закрытый ключ, сгенерированный KeyStoreGenerator в текстовом формате (например, хранилище хранилища) - Java - PullRequest
0 голосов
/ 26 сентября 2018

Я использую следующий код для создания открытого и закрытого ключа в целях безопасности.

public KeyGenerator(int keylength) throws NoSuchAlgorithmException, NoSuchProviderException {
    this.keyGen = KeyPairGenerator.getInstance("RSA");
    this.keyGen.initialize(keylength);
}

public void createKeys() {
    this.pair = this.keyGen.generateKeyPair();
    this.privateKey = pair.getPrivate();
    this.publicKey = pair.getPublic();
}

public PrivateKey getPrivateKey() {
    return this.privateKey;
}

public PublicKey getPublicKey() {
    return this.publicKey;
}

public void writeToFile(String path, byte[] key) throws IOException {
    File f = new File(path);
    f.getParentFile().mkdirs();

    FileOutputStream fos = new FileOutputStream(f);
    fos.write(key);
    fos.flush();
    fos.close();
}

public static void main(String[] args) {
    KeyGenerator kg;
    try {
        kg = new KeyGenerator(2048);
        kg.createKeys();
        System.out.println(kg.getPublicKey().getFormat()); // this prints out X.509

        System.out.println(kg.getPrivateKey().getFormat()); // this prints out PKCS#8

        kg.writeToFile(PUBLIC_KEY_PATH, kg.getPublicKey().getEncoded());
        kg.writeToFile(PRIVATE_KEY_PATH, kg.getPrivateKey().getEncoded());
    } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
        System.err.println(e.getMessage());
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }

}

Мне нужно найти способ сохранить в хранилище закрытый ключ (который выглядит следующим образомизображение) в следующем формате.В тот момент, когда я открываю ключ в текстовом редакторе, я получаю что-то вроде следующего:

enter image description here

Есть ли способ конвертировать этот PKCS # 8 вкодировка, подходящая для хранения в файле?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Обратите внимание, что в отношении getFormat Javadoc это стандартный формат ASN.1:

Возвращает имя основного формата кодировки этого ключа или ноль, если этот ключ делаетне поддерживает кодирование.Основной формат кодирования назван в терминах соответствующего формата данных ASN.1, если существует спецификация ASN.1 для этого ключа.Например, имя формата данных ASN.1 для открытых ключей - SubjectPublicKeyInfo, как определено стандартом X.509;в этом случае возвращается формат «X.509».Точно так же имя формата данных ASN.1 для закрытых ключей - PrivateKeyInfo, как определено стандартом PKCS # 8;в этом случае возвращаемым форматом является «PKCS # 8».

Но, если нам нужно изменить его по какой-либо причине, мы можем использовать Bouncy Castle: Например:

  //Convert to PKCS#1
  PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(kg.getPrivateKey().getEncoded());
  ASN1Encodable encodable = pkInfo.parsePrivateKey();
  ASN1Primitive primitive = encodable.toASN1Primitive();
  byte[] privateKeyPKCS1 = primitive.getEncoded();
  //kg.writeToFile(PRIVATE_KEY_PATH, privateKeyPKCS1);

  //Convert to PEM
  PemObject pemObject = new PemObject("RSA PRIVATE KEY", privateKeyPKCS1);
  StringWriter stringWriter = new StringWriter();
  PemWriter pemWriter = new PemWriter(stringWriter);
  pemWriter.writeObject(pemObject);
  pemWriter.close();
  String pemString = stringWriter.toString();
  kg.writeToFile(PRIVATE_KEY_PATH, pemString.getBytes());

Мы получим файл, подобный следующему:

-----BEGIN RSA PRIVATE KEY----- 
MIIEpQIBAAKCAQEAr76DpCYkQKMCKRyjx9wyVKihU4vSBeTq7VpkJx9g616AUTtI
yzMZyHa2vVucgkZL9VFS+ZwJZk7b6pNUUSwnwKxHFnRndid2Hum1ZZZCzRYwhsKq
. . . 
XIA+HTgaXbEsCyDcX7EWVlpnTzq5ASO2llKT8V0Mswyh2fznbm5nH92fUKUku2nL 
VAQC2f8PL2eLec3wmb0ZWBazadakMC1fVH3umiBmFnkyDoEfojdOgSo=
-----END RSA PRIVATE KEY-----

Я использовал эту версию BouncyCastle:

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15on</artifactId>
  <version>1.60</version>
</dependency>

Этот вопрос говорит о той же проблеме, но для кодировки открытого ключа: Генерация ключей RSA в формате PKCS # 1 в Java

Благодаря комментарию @ dave_thompson_085 я реализовал другой способ сделать это, используя класс JcaMiscPEMGenerator

  JcaMiscPEMGenerator generator = new JcaMiscPEMGenerator(kg.getPrivateKey());
  stringWriter = new StringWriter();
  pemWriter = new PemWriter(stringWriter);
  pemWriter.writeObject(generator.generate());
  pemWriter.close();
  pemString = stringWriter.toString();
  kg.writeToFile(PRIVATE_KEY_PATH, pemString.getBytes());

Чтобы использовать его, нам нужно добавить следующую зависимость:

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcpkix-jdk15on</artifactId>
  <version>1.60</version>
</dependency>
0 голосов
/ 26 сентября 2018

Я чувствую себя довольно глупо сейчас, когда я потратил на это часы .. Я поставлю ответ здесь.

Итак, проблема в том, что я хочу сохранить в виде строки (в текстовом файле содержимоедвоичный файл - как тот, который изображен на картинке выше)

Если вы используете систему на основе Unix, вы можете легко получить его:

base64 filename.key > string.txt

сейчас, если вы хотите, чтобы вашназад двоичный файл, так же просто, как:

base64 -D string.txt > filename-clone.key

Так что это был не тот вопрос, связанный с Java

...