以文本格式存储 KeyStoreGenerator 生成的私钥(例如保管库存储)- Java

Store private key generated by KeyStoreGenerator in text format (for eg. vault store) - Java

出于安全目的,我正在使用以下代码创建一个 public 和一个私钥。

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());
    }

}

我需要找到一种方法以下列格式将私钥(如下图所示)存储在保险库中。当我用文本编辑器打开密钥时,我得到如下内容。

是否可以将此 PKCS#8 转换为适合存储在文件中的编码?

谢谢!

现在我花了几个小时在这上面,我觉得很愚蠢..我会把答案放在这里。

所以问题是我想将其存储为字符串(在文本文件中存储二进制文件的内容 - 如上图所示)

如果您使用的是基于 unix 的系统,您可以通过以下方式轻松获得它:

base64 filename.key > string.txt

现在,如果您想要恢复二进制文件,就像:

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

所以不是 java 相关问题

请注意,关于 getFormat Javadoc,这是 ASN.1 标准格式:

Returns the name of the primary encoding format of this key, or null if this key does not support encoding. The primary encoding format is named in terms of the appropriate ASN.1 data format, if an ASN.1 specification for this key exists. For example, the name of the ASN.1 data format for public keys is SubjectPublicKeyInfo, as defined by the X.509 standard; in this case, the returned format is "X.509". Similarly, the name of the ASN.1 data format for private keys is PrivateKeyInfo, as defined by the PKCS #8 standard; in this case, the returned format is "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>

This question 谈论相同的问题,但对于 public 密钥编码:Generating RSA keys in PKCS#1 format in Java

感谢@dave_thompson_085 的评论,我意识到使用 class 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>