什么是使用java的KeyPairGenerator的openssl等价物?

时间:2015-10-21 21:13:48

标签: java encoding cryptography rsa key-pair

首先,我试图在安全问题上提出这个问题 - 我得到了一些赞成,但似乎现在已经没有答案了。我知道这是openssl相关的,但它源于使用java KeyPairGenerator对象,所以我觉得它可能对堆栈溢出有效。请参阅以下代码:

我一直在使用java的KeyPairGenerator来生成程序中的公钥/私钥,以便我可以加密和解密文件(也使用java加密/解密方法)。我希望能够转移到使用openssl来生成这些公共私钥对,但是当我使用命令行生成的openssl密钥解密我的文件时,我不断得到填充异常。例如,我尝试使用openssl来生成密钥,而不是使用java的KeyPairGenerator:

openssl rsa -in keypair.pem -outform DEF -pubout -out public.der
openssl pkcs8 -topk8 -nocrypt -in keypair.pem -outform DER -out private.der

我尝试使用DER文件加密/解密我的文件。最终,我尝试的每种关键格式似乎都给我带来了问题。

我认为这意味着我的openssl命令中的键格式与java的KeyPairGenerator的工作方式不匹配。以下是我的密钥生成代码的片段:

public void createPublicPrivateKeys() throws IOException, NoSuchAlgorithmException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    logger.info("Password to encrypt the private key: ");
    String password = in.readLine();
    logger.info("Generating an RSA keypair.");

    // Create an RSA key key pair
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(4096);
    KeyPair keyPair = keyPairGenerator.genKeyPair();

    logger.info("Done generating the keypair.\n");

    // Write public key out to a file
    String publicKeyFilename = "publicKey.der";
    logger.info("Public key filename: " + publicKeyFilename);

    // Get  encoded form of the public key for future usage -- this is X.509 by default.
     byte[] publicKeyBytes = keyPair.getPublic().getEncoded();

     // Write the encoded public key
     FileOutputStream fos = new FileOutputStream(publicKeyFilename);
     fos.write(publicKeyBytes);
     fos.close();

     String privateKeyFilename = "privateKey.der";
     logger.info("Private key filename: " + privateKeyFilename);

     // Get the encoded form -- PKCS#8 by default.
     byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

     // Encrypt the password
     byte[] encryptedPrivateKeyBytes = new byte[0];
     try {
         encryptedPrivateKeyBytes = passwordEncrypt(password.toCharArray(), privateKeyBytes);
     } catch (Exception e) {
         e.printStackTrace();
     }

     fos = new FileOutputStream(privateKeyFilename);
     fos.write(encryptedPrivateKeyBytes);
     fos.close();
 }

使用java的标准KeyPairGenerator的openssl等效命令行语句是什么?另请注意,使用诸如充气城堡等外部包裹不是一种选择。

1 个答案:

答案 0 :(得分:1)

OpenSSL命令行rsapkcs8不生成密钥对;它们只能从一种形式转换为另一种形式和/或显示。对于RSA(仅限),genrsa生成密钥对,采用OpenSSL的“遗留”私钥格式,该格式与Java无法(轻松)兼容。您的rsapkcs8命令会将旧格式转换为Java优先选择的“X.509”(SPKI)和PKCS#8 DER格式。自1.0.0以来的OpenSSL也有genpkey,它为所有支持的非对称算法(包括RSA)生成密钥或适用的参数,默认为PKCS#8输出。

您的Java代码的passwordEncrypt步骤不是标准Java,也没有解释。 OpenSSL库支持根据该标准对PKCS#8进行基于密码的加密,如果这是passwordEncrypt所做的,但大多数OpenSSL命令行功能都没有。 如果您尝试在Java中使用您的示例的private.der尝试对其进行任何类型的基于密码(或其他)的解密,那么这将无效,因为它未加密;它甚至不是用于加密密钥的PKCS#8结构。 但是,之前会发生错误,甚至会尝试解密任何数据,或者更有可能解密工作密钥。