2017-04-10 10 views
1

acme 클라이언트 acme4j : https://github.com/shred/acme4j을 사용하여 SSL 인증서를 만들었습니다.확장 기능을 알 수 없음 : 생성 된 인증서에 DER로 인 코드 된 OCTET 문자열 오류가 발생했습니다.

그러나 자체 서명 된 인증서를 생성하는 동안 구문 분석 중에 예외가 발생합니다. 여기에 내 생성 된 인증서입니다 :

{Version: V3 
Subject: T=spid: yuz8xxz 
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

Key: Sun RSA public key, 2048 bits 
modulus: 

public exponent: 65537 
Validity: [From: Mon Apr 10 17:56:36 IST 2017, 
      To: Mon Apr 17 17:56:36 IST 2017] 
Issuer: T=spid: yuz8xxz 
SerialNumber: [ 015b57d4 807c] 

Certificate Extensions: 1 
[1]: ObjectId: 1.3.6.1.5.5.7.1.26 Criticality=false 


**Extension unknown: DER encoded OCTET string =** 
0000: 04 23 30 21 A0 12 16 07 79 75 7A 38 78 78 7A 16 .#0!....yuz8xxz. 
0010: 07 79 75 7A 38 78 78 7A A1 0B 16 06 31 32 33 34 .yuz8xxz....1234 
0020: 35 36 02 01 01          56... 


] 
Algorithm: [SHA256withRSA] 
Signature: 
] 
} 
+0

정확히 acme4j 코드를 사용하고 있습니까? –

답변

2

Acme4j 코드는 java.security.cert.X509Certificate 클래스를 사용합니다. 이 클래스의 toString() 메서드는 Sun의 기본 공급자을 사용하는 경우 "확장명을 알 수 없음" 출력 (corresponding code에 따라)을 생성합니다.

올바르게 구문 분석 (형식화 된 출력 얻기)하려면이 확장을 구문 분석 할 코드를 포함하여 acme4j의 코드를 변경하거나 직접 작성해야합니다. 내 시험 (자바 7 BouncyCastle 1.56)에서

, 나는 X509Certificate에 래퍼를 작성 BouncyCastle의 코드를 기반으로 format 방법을 만들어 (나는 대부분의 복사 및 단지 TNAuthorizationList 연장 코드를 추가). 아래의 코드는 최적이 아닙니다 (잘못된 예외 처리 및 일부 사용되지 않는 클래스).하지만 아이디어를 얻을 수 있습니다.

X509Certificate cert = ... 
System.out.println("Certificate " + new CertificateWrapper(cert).format()); 

출력 형식은 SUN의 디폴트의 프로 바이더는 다른,하지만 당신은 당신이 필요로하는 것을 얻기 위해 그것을 사용자 정의 할 수 있습니다

import org.bouncycastle.asn1.*; 
import org.bouncycastle.asn1.misc.*; 
import org.bouncycastle.asn1.util.ASN1Dump; 
import org.bouncycastle.asn1.x509.*; 
import org.bouncycastle.util.encoders.Hex; 

public class CertificateWrapper { 

    private X509Certificate cert; 

    public CertificateWrapper(X509Certificate cert) { 
     this.cert = cert; 
    } 

    public String format() throws Exception { 
     StringBuffer buf = new StringBuffer(); 
     String nl = System.getProperty("line.separator"); 

     buf.append(" [0]   Version: ").append(this.cert.getVersion()).append(nl); 
     buf.append("   SerialNumber: ").append(this.cert.getSerialNumber()).append(nl); 
     buf.append("    IssuerDN: ").append(this.cert.getIssuerDN().toString()).append(nl); 
     buf.append("   Start Date: ").append(this.cert.getNotBefore()).append(nl); 
     buf.append("   Final Date: ").append(this.cert.getNotAfter()).append(nl); 
     buf.append("   SubjectDN: ").append(this.cert.getSubjectDN().toString()).append(nl); 
     buf.append("   Public Key: ").append(this.cert.getPublicKey()).append(nl); 
     buf.append(" Signature Algorithm: ").append(this.cert.getSigAlgName()).append(nl); 

     byte[] sig = this.cert.getSignature(); 

     buf.append("   Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl); 
     for (int i = 20; i < sig.length; i += 20) { 
      if (i < sig.length - 20) { 
       buf.append("      ").append(new String(Hex.encode(sig, i, 20))).append(nl); 
      } else { 
       buf.append("      ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl); 
      } 
     } 

     TBSCertificateStructure tbs = TBSCertificateStructure.getInstance(ASN1Sequence.fromByteArray(cert.getTBSCertificate())); 
     X509Extensions extensions = tbs.getExtensions(); 

     if (extensions != null) { 
      Enumeration e = extensions.oids(); 

      if (e.hasMoreElements()) { 
       buf.append("  Extensions: \n"); 
      } 

      while (e.hasMoreElements()) { 
       ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement(); 
       X509Extension ext = extensions.getExtension(oid); 

       if (ext.getValue() != null) { 
        byte[] octs = ext.getValue().getOctets(); 
        ASN1InputStream dIn = new ASN1InputStream(octs); 
        buf.append("      critical(").append(ext.isCritical()).append(") "); 
        try { 
         if (oid.equals(Extension.basicConstraints)) { 
          buf.append(BasicConstraints.getInstance((ASN1Sequence) dIn.readObject())).append(nl); 
         } else if (oid.equals(Extension.keyUsage)) { 
          buf.append(KeyUsage.getInstance((DERBitString) dIn.readObject())).append(nl); 
         } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) { 
          buf.append(new NetscapeCertType((DERBitString) dIn.readObject())).append(nl); 
         } else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) { 
          buf.append(new NetscapeRevocationURL((DERIA5String) dIn.readObject())).append(nl); 
         } else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) { 
          buf.append(new VerisignCzagExtension((DERIA5String) dIn.readObject())).append(nl); 
         //********************************************************* 
         // *** HERE: code to handle TNAuthorizationList *** 
         //********************************************************* 
         } else if (oid.equals(TNAuthorizationList.TN_AUTH_LIST_OID)) { 
          buf.append(TNAuthorizationList.getInstance((ASN1Sequence) dIn.readObject())).append(nl); 
         } else { 
          buf.append(oid.getId()); 
          buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl); 
         } 
        } catch (Exception ex) { 
         buf.append(oid.getId()); 
         buf.append(" value = ").append("*****").append(nl); 
        } 
       } else { 
        buf.append(nl); 
       } 
      } 
     } 

     return buf.toString(); 
    } 
} 

그런 다음, 당신은 단지 X509Certificate 대신이 래퍼를 사용합니다.


PS :이 질문은 보완 (또는 "속편") this one합니다. OP 코드는 here이고 TNAuthorizationList 클래스는 accepted answer입니다. 그러나이 질문은 다른 문제 (관련이 있지만 다른 것)이기 때문에 별도의 질문으로 다루었습니다.

+0

Hugo, 이전 질문에서 참조 용으로 코드 스 니펫을 추가했습니다. 다시 한번 감사드립니다. –

2

1.3.6.1.5.5.7.1.26은 초안 문서 (https://datatracker.ietf.org/doc/draft-ietf-stir-certificates/)에 정의 된 전화 번호 (TN) 인증 목록에 대한 OID 것 같다; BouncyCastle은 예쁜 프린터를 가지고 있지 않으므로 원시 코드화 된 페이로드를 보여줍니다.

나는 전화 전문가가 아니지만 ('yuz8xxz', 'yuz8xxz')는 유효한 서비스 공급자 코드 목록이 아니며 '123456'은 (는) '123456'이 유효한 전화 번호 범위. 따라서이 인증서 확장을 사용하여 찾고있는 것이 무엇인지 명확하지 않습니다. Let 's Encrypt를 사용하면 매우 놀랍습니다.

+0

전달 된 값은 테스트 용도로만 사용됩니다. 예 BC 프린터가 없습니다. –