2016-09-30 3 views
2

PEM을 가져 와서 bouncycastle을 통해 PKCS 키 저장소에 추가 한 다음 java crypto를 사용하여 PKCS 키 저장소 값을 JKS 키 저장소로 가져 오는 코드를 작성했습니다.알고리즘 HmacPBESHA256을 사용할 수 없음

나는 항상 나를 아래 변경 가능 뭔가하지만 난 알아낼 수 없습니다, I는 단위 테스트 통과했다 어제가 성공적으로 다음 단계를 실행하는 데,하지만 오늘 아침에 내가 지금이

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] 

을 때리기 시작 맹세 무엇을 였다. 그것은 공급자가 내가 그 알고리즘을 사용하여 이후 사라진 것으로 보인다.

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 

코드에 훨씬이 아니다 :

여기 내 java.security 파일 조각입니다. 먼저 bouncycastle을 통해 PKCS 키 저장소를 만들고 pem을 추가 한 다음 PKCS12로 디스크에 저장합니다. 그런 다음 JKS로 저장하지 않고 Java 암호화를 통해 가져옵니다.

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 명시 적으로 추가되었습니다. 어떤 제안?

업데이트 : 제안에 대해 감사합니다. dave_thompson_085. 내가 오버로드 된 메소드를 보지 못했다고는 믿을 수 없지만, 솔루션은 Keystore.getInstance ("PKCS12", "BC") 호출에서 제공자를 지정하는 것이 었습니다.

+0

[이 버그] (https://bugs.openjdk.java.net/browse/JDK-8013493)와 관련된 인터넷 검색 결과가 표시 될 수 있습니다. 또한 Bouncy Castle 제공자는 어디에도 보이지 않습니다. 어쩌면 도움이 될까요? –

+0

일부 코드를 편집하여 문제를 재생하면 도움이됩니다. –

+1

BC 공급자를 추가해도 우선 순위가 부여되지 않습니다. stacktrace는 SunJSSE 공급자의 구현을 확인합니다. 'KeyStore.getInstance ("PKCS12", "BC")를 사용하거나, 위험한 상태로 살기를 원한다면 ** 위치 4 이하의 BC 제공자를 삽입하십시오. 또는 SHA1을 사용하여 PKCS12에서 PB-MAC을 수행하십시오 다른 모든 사람들처럼 - 당신은 이미 PBE를 위해 그것을 사용하고 있습니다. 게다가 그것은 당신이 강력하게 cert를 암호화하는 것처럼 보입니다 - 왜? –

답변

0

dave_thompson_085에 지적했듯이 키 스토어에 사용할 공급자를 지정할 수 있습니다. 처음에 getInstance() 오버로드를 놓친 것처럼이 사실을 알지 못했습니다.

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

너무 쉽게 :이 호출 요약 그래서

, 내 문제를 해결.