【问题标题】:Java load encrypted private keyJava加载加密私钥
【发布时间】:2021-09-22 02:02:17
【问题描述】:

我花了太长时间寻找可以加载由 openssl 证书创建自动生成的加密私钥的解决方案。

使用密码生成证书和新私钥:password

openssl req -newkey rsa:2048 -x509 -keyout test.key -out test.crt -days 365

我已经提取了代码的重要部分

package test;

import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.bouncycastle.util.encoders.Base64;
import org.junit.jupiter.api.BeforeEach;

import javax.crypto.Cipher;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.KeySpec;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Log4j2
class pkShould {
    
    private static final String PASS_PHRASE = "password";

    @SneakyThrows
    @BeforeEach
    public void setup() {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        Path pKPath = Paths.get(cl.getResource("keystore/test.key").toURI());
        try(Stream<String> lines = Files.lines(pKPath)) {
            String encrypted = lines.collect(Collectors.joining("\n"));
            encrypted = encrypted.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "");
            encrypted = encrypted.replace("-----END ENCRYPTED PRIVATE KEY-----", "");
            byte[] content = Base64.decode(encrypted);

            EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(content);
            Cipher cipher = Cipher.getInstance(encryptPKInfo.getAlgName());
            PBEKeySpec pbeKeySpec = new PBEKeySpec(PASS_PHRASE.toCharArray());
            SecretKeyFactory secFac = SecretKeyFactory.getInstance(encryptPKInfo.getAlgName());
            Key pbeKey = secFac.generateSecret(pbeKeySpec);
            AlgorithmParameters algParams = encryptPKInfo.getAlgParameters();
            cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
            KeySpec pkcs8KeySpec = encryptPKInfo.getKeySpec(cipher);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PrivateKey expectedPrivateKey = kf.generatePrivate(pkcs8KeySpec);
        }
    }
}

永远不会超过EncryptedPrivateKeyInfo,据我所知,私钥形成正确并且在 keyStore 中使用得很好。

堆栈跟踪

java.io.IOException: ObjectIdentifier() -- data isn't an object ID (tag = 48)

    at sun.security.util.ObjectIdentifier.<init>(ObjectIdentifier.java:285)
    at sun.security.util.DerInputStream.getOID(DerInputStream.java:321)
    at com.sun.crypto.provider.PBES2Parameters.engineInit(PBES2Parameters.java:267)
    at java.security.AlgorithmParameters.init(AlgorithmParameters.java:293)
    at sun.security.x509.AlgorithmId.decodeParams(AlgorithmId.java:150)
    at sun.security.x509.AlgorithmId.<init>(AlgorithmId.java:132)
    at sun.security.x509.AlgorithmId.parse(AlgorithmId.java:416)
    at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:95)

非常感谢任何帮助。

【问题讨论】:

    标签: java encryption openssl rsa private-key


    【解决方案1】:

    不幸的是,这个错误非常无用。它真正的意思是'java不喜欢它'。它可能意味着几乎任何东西:密钥受到密码短语密码和/或 java 不喜欢的比特大小的保护,密钥本身使用 java 不喜欢的密码/比特大小,密钥的格式不是 PKCS#8。

    看起来您生成了 x509 格式的密钥,这可能无法正常工作。也许转换它会起作用;试试这个:

    openssl pkcs8 -topk8 \ 
    -inform PEM -outform PEM \ 
    -in key.pem -out key-pkcs8.pem
    

    【讨论】:

    • 做到了...怎么可能制作 x509 私钥,我假设 -x509 仅适用于 -out test.crt。我显然需要进一步阅读。
    • @Matthew.Lothian:你说得对,真的没有 X.509 私钥这样的东西。一些 openssl 命令以自己的格式而不是更标准的格式创建密钥。不要责怪 openssl,它们的存在时间比 Java 还长!
    • @PresidentJamesK.Polk:实际上,openssl req -newkey -keyout 确实创建了 PKCS8,正如 PEM 标签 BEGIN/END ENCRYPTED PRIVATE KEY 所证实的那样。但是它使用的是PBES2方案,8u301或11.0.1以下的Java有一个错误解析PBES2参数的bug;请参阅“数据不是对象 ID (tag=48)”的许多其他 Q(顺便说一句,它准确地标识了这个问题,没有其他问题)。 openssl pkcs8 -topk8 in 1.0.x 默认为(非常不安全!)Java 可以处理的 PBES1 方案,但如果您使用例如-v2 aes128 或 OpenSSL 1.1.x 会产生同样的问题。
    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 2013-04-06
    • 1970-01-01
    • 2011-03-20
    • 2018-02-27
    相关资源
    最近更新 更多