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

时间:2018-09-26 14:02:15

标签: java pkcs#8

出于安全目的,我正在使用以下代码创建公用密钥和专用密钥。

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 :(得分:2)

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

  

返回此键的主要编码格式的名称;如果此键不支持编码,则返回null。如果存在针对此密钥的ASN.1规范,则根据适当的ASN.1数据格式来命名主要编码格式。例如,公共密钥的ASN.1数据格式的名称是X.509标准定义的SubjectPublicKeyInfo。在这种情况下,返回的格式为“ 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>

这个问题讨论的是相同的问题,只是公共密钥编码:Generating RSA keys in PKCS#1 format in 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>

答案 1 :(得分:1)

现在我已经花了几个小时了,我感到非常愚蠢。我将答案放在这里。

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

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

base64 filename.key > string.txt

现在,如果您要恢复二进制文件,就很简单:

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

所以这不是与Java相关的问题