首先,我试图在安全问题上提出这个问题 - 我得到了一些赞成,但似乎现在已经没有答案了。我知道这是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等效命令行语句是什么?另请注意,使用诸如充气城堡等外部包裹不是一种选择。
答案 0 :(得分:1)
OpenSSL命令行rsa
或pkcs8
不生成密钥对;它们只能从一种形式转换为另一种形式和/或显示。对于RSA(仅限),genrsa
生成密钥对,采用OpenSSL的“遗留”私钥格式,该格式与Java无法(轻松)兼容。您的rsa
和pkcs8
命令会将旧格式转换为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结构。
但是,之前会发生错误,甚至会尝试解密任何数据,或者更有可能解密工作密钥。