算法 HmacPBESHA256 不可用 [英] Algorithm HmacPBESHA256 not available

查看:470
本文介绍了算法 HmacPBESHA256 不可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我编写了一些代码来获取 PEM,通过 bouncycastle 将其添加到 PKCS 密钥库,然后使用 java crypto 将 PKCS 密钥库值导入 JKS 密钥库.

So, I have written some code to take a PEM, add it to a PKCS keystore via bouncycastle, and then use java crypto to import the PKCS keystore value into a JKS keystore.

我发誓昨天我在执行这些步骤后成功通过了单元测试,但今天早上我开始尝试这个

I swear that yesterday I had a unit test pass successfully having executed these steps, but this morning I started hitting this

Caused by: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available
    at javax.crypto.Mac.getInstance(Mac.java:181) ~[na:1.8.0_60]
    at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2039) ~[na:1.8.0_65]

现在,总有可能在我下面发生了一些变化,但我无法弄清楚它是什么.似乎我 用于该算法的任何提供程序已经消失了.

Now, it's always possible something changed underneath me but I cannot figure out what it was. It seems whatever provider I was using for that algorithm has since disappeared.

这是我的 java.security 文件片段:

here's my java.security file snippet:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=apple.security.AppleProvider

代码并不多.首先,我通过 bouncycastle 创建一个 PKCS 密钥库,添加一个 pem 并以 PKCS12 的形式保存到磁盘.然后通过 java crypto 导入,保存为 JKS.

There's not a whole lot to the code. First I create a PKCS keystore via bouncycastle, adding a pem and saving to disk as PKCS12. Then import via java crypto, saving back out as JKS.

   public KeystoreBuilder createJksFromPem(String pemPrivate, String pemPublic, String alias) throws Exception
    {
        Preconditions.checkState(StringUtils.isNotEmpty(pemPrivate), "pemPrivate must not be empty");
        Preconditions.checkState(StringUtils.isNotEmpty(pemPublic), "pemPublic must not be empty");
        Preconditions.checkState(StringUtils.isNotEmpty(alias), "alias must not be empty");

        String pkcsFilename = filename + ".pkcs";
        convertPemToPkcs(pemPrivate, pemPublic, pkcsFilename);

        importPkcsIntoJks(pkcsFilename);

        return this;
    }

    private void importPkcsIntoJks(String pkcsFilename) throws Exception
    {
        KeyStore pkcs = KeyStore.getInstance("PKCS12");
        File pkcsFile = new File(pkcsFilename);
        try (FileInputStream fis = new FileInputStream(pkcsFile))
        {
            pkcs.load(fis, password.toCharArray());
        }
        pkcsFile.delete();

        KeyStore jks = KeyStore.getInstance("JKS");
        jks.load(null);

        Enumeration<String> aliases = pkcs.aliases();
        while (aliases.hasMoreElements())
        {
            String alias = aliases.nextElement();
            if (!pkcs.isKeyEntry(alias))
            {
                continue;
            }
            Key key = pkcs.getKey(alias, password.toCharArray());
            Certificate[] chain = pkcs.getCertificateChain(alias);

            jks.setKeyEntry(alias, key, password.toCharArray(), chain);
        }

        persist(jks);
    }

    private void convertPemToPkcs(String pemPrivate, String pemPublic, String pkcsFilename) throws IOException, NoSuchAlgorithmException, OperatorCreationException, PKCSException, FileNotFoundException
    {
        Security.addProvider(new BouncyCastleProvider());

        X509CertificateHolder cert = (X509CertificateHolder) readObject(pemPublic);
        PEMKeyPair keyPair = (PEMKeyPair) readObject(pemPrivate);

        JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
        PKCS12SafeBagBuilder pkcs12BagBuilder = new PKCS12SafeBagBuilder(cert);
        pkcs12BagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Kafka SSL Certificate"));
        pkcs12BagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(keyPair.getPublicKeyInfo()));

        PKCS12PfxPduBuilder builder = new PKCS12PfxPduBuilder();

        builder.addData(pkcs12BagBuilder.build());

        builder.addEncryptedData(new JcePKCSPBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC).setProvider("BC").build(password.toCharArray()), pkcs12BagBuilder.build());

        PKCS12PfxPdu pfx = builder.build(new JcePKCS12MacCalculatorBuilder(NISTObjectIdentifiers.id_sha256), password.toCharArray());

        try (FileOutputStream fos = new FileOutputStream(new File(pkcsFilename)))
        {
            fos.write(pfx.getEncoded(ASN1Encoding.DL));
        }
    }

然后砰的一声炸开

pkcs.load(fis, password.toCharArray());

如您所见,BouncyCastleProvider 已显式添加.有什么建议么?

As you can see, the BouncyCastleProvider was added explicitly. Any suggestions?

更新:感谢 dave_thompson_085 的建议.不敢相信我没有看到那个重载的方法,但解决方案是在调用 get Keystore.getInstance("PKCS12", "BC") 中指定提供者.

UPDATE: Thanks dave_thompson_085 for the suggestion. Can't believe I didn't see that overloaded method, but the solution was to specify the provider in the call get Keystore.getInstance("PKCS12", "BC").

推荐答案

正如 dave_thompson_085 所指出的,我可以指定要用于密钥库的提供程序.我最初没有意识到这一点,因为我错过了 getInstance() 重载.

as dave_thompson_085 pointed out, I can specify which provider I want to be used for the keystore. I didn't realize this initially as I missed the getInstance() overload.

总而言之,调用此方法解决了我的问题:

So in summary, calling this fixed my issue:

KeyStore.getInstance("PKCS12","BC")

太简单了.

这篇关于算法 HmacPBESHA256 不可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆