如何在由openssl生成的java中使用.key和.crt文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6482484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:17:55  来源:igfitidea点击:

How to use .key and .crt file in java that generated by openssl?

javasslcryptographyopensslcrt

提问by Sajad Bahmani

I need asymmetric encryption in java. I generate .key and .crt files with own password and .crt file by openssl that said in http://www.imacat.idv.tw/tech/sslcerts.html.
How to use these .key and .crt file to extract publickey and private key in Java?

我需要 Java 中的非对称加密。我使用自己的密码和 .crt 文件生成 .key 和 .crt 文件,由http://www.imacat.idv.tw/tech/sslcerts.html中说的 openssl 生成。
如何使用这些 .key 和 .crt 文件在 Java 中提取公钥和私钥?

采纳答案by Bruno

Your .keyand .crtfiles may be in PEM format. To check this open them with a text editor and check whether the content looks like ------BEGIN CERTIFICATE------(or "begin RSA private key"...). This is generally the default format used by OpenSSL, unless you've explicitly specified DER.

您的.key.crt文件可能是 PEM 格式。要检查这一点,请使用文本编辑器打开它们并检查内容是否看起来像------BEGIN CERTIFICATE------(或“开始 RSA 私钥”...)。这通常是 OpenSSL 使用的默认格式,除非您明确指定了 DER。

It's probably not required (see below), but if your certificate is in DER format (a binary format), you can convert them in PEM format using:

它可能不是必需的(见下文),但如果您的证书是 DER 格式(二进制格式),您可以使用以下方法将它们转换为 PEM 格式:

openssl x509 -inform DER -in cert.crt -outform PEM -out cert.pem

(Check the help for openssl rsafor doing something similar with the private key if needed.)

openssl rsa如果需要,请查看有关使用私钥执行类似操作的帮助。)

You then get two options:

然后你有两个选择:

  • Build a PKCS#12 file

    openssl pkcs12 -export -in myhost.crt -inkey myhost.key -out myhost.p12
    
  • 构建一个 PKCS#12 文件

    openssl pkcs12 -export -in myhost.crt -inkey myhost.key -out myhost.p12
    

You can then use it directly from Java as a keystore of type "PKCS12". Most Java applications should allow you to specify a keystore type in addition to the file location. For the default system properties, this is done with javax.net.ssl.keyStoreType(but the application you're using might not be using this). Otherwise, if you want to load it explicitly, use something like this:

然后,您可以直接从 Java 使用它作为“PKCS12”类型的密钥库。除了文件位置之外,大多数 Java 应用程序应该允许您指定密钥库类型。对于默认系统属性,这是通过javax.net.ssl.keyStoreType(但您正在使用的应用程序可能没有使用它)完成的。否则,如果您想显式加载它,请使用以下内容:

KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis =
    new FileInputStream("/path/to/myhost.p12");
ks.load(fis, "password".toCharArray()); // There are other ways to read the password.
fis.close();

(Then, you should be able to iterate through the aliases()of the KeyStoreand use getCertificate(and then getPublicKey()for the public key) and getKey().

(然后,你应该能够通过迭代aliases()KeyStore和使用getCertificate(再getPublicKey()为公钥)和getKey()

  • Use BouncyCastle's PEMReader.

     FileReader fr = ... // Create a FileReader for myhost.crt
     PEMReader pemReader = new PEMReader(fr);
     X509Certificate cert = (X509Certificate)pemReader.readObject();
     PublicKey pk = cert.getPublicKey();
     // Close reader...
    
  • 使用BouncyCastlePEMReader.

     FileReader fr = ... // Create a FileReader for myhost.crt
     PEMReader pemReader = new PEMReader(fr);
     X509Certificate cert = (X509Certificate)pemReader.readObject();
     PublicKey pk = cert.getPublicKey();
     // Close reader...
    

For the private key, you'll need to implement a PasswordFinder(see link from PEMReader doc) for constructing the PEMReaderif the private key is password-protected. (You'll need to cast the result of readObject()into a Keyor PrivateKey.)

对于私钥,您需要实现一个PasswordFinder(参见 PEMReader 文档中的链接)来构造PEMReader私钥是否受密码保护。(您需要将 的结果readObject()转换为 aKeyPrivateKey。)

回答by Kirby

Take a look at org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator

看看 org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator

回答by Eugene Mayevski 'Callback

As I understand it, OpenSSL has saved files in so-called PEM format. You need to convert it to Java Key Storage (JKS) format, then work with that format (which is native to Java) to extract files. For conversion please use this Google query, it gives pretty good results.

据我了解,OpenSSL 以所谓的 PEM 格式保存文件。您需要将其转换为 Java 密钥存储 (JKS) 格式,然后使用该格式(Java 原生的)来提取文件。对于转换,请使用此 Google 查询,它提供了非常好的结果。

Load the JKS file to java.security.KeyStore class. Then use getCertificate and getKey methods to get the needed information.

将 JKS 文件加载到 java.security.KeyStore 类。然后使用 getCertificate 和 getKey 方法来获取所需的信息。

回答by Muggles Merriweather

This should do what you want to do (using the BouncyCastle PEMReader as suggested above) -- take a PEM-encoded private key + certificate, and output a PKCS#12 file. Uses the same password for the PKCS12 that was used to protect the private key.

这应该做你想做的事情(使用上面建议的 BouncyCastle PEMReader)——采用 PEM 编码的私钥 + 证书,并输出一个 PKCS#12 文件。对用于保护私钥的 PKCS12 使用相同的密码。

public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password) throws Exception {
    // Get the private key
    FileReader reader = new FileReader(keyFile);

    PEMReader pem = new PEMReader(reader, new PasswordFinder() {
        @Override public char[] getPassword() {
            return password.toCharArray();
        }
    });

    PrivateKey key = ((KeyPair)pem.readObject()).getPrivate();

    pem.close();
    reader.close();

    // Get the certificate      
    reader = new FileReader(cerFile);
    pem = new PEMReader(reader);

    X509Certificate cert = (X509Certificate)pem.readObject();

    pem.close();
    reader.close();

    // Put them into a PKCS12 keystore and write it to a byte[]
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(null);
    ks.setKeyEntry("alias", (Key)key, password.toCharArray(), new java.security.cert.Certificate[]{cert});
    ks.store(bos, password.toCharArray());
    bos.close();
    return bos.toByteArray();
}