2016-09-27 2 views
0

나는 살아야 할 이상한 요구 사항이 있습니다. 암호화 시스템에 TBS 인증서를 전달해야합니다. 서명 한 인증서의 문자열을 서명 된 인증서를 만들기 위해 인증서에 통합해야합니다.인증서에 서명 추가

SO.COM에서 com.ibm.security.x509.X509CertImpl 및 다양한 BouncyCastle 게시물을 보면 어떻게 수행 할 수 없는지 알 수 있습니다.

질문 :

이 가능합니까? 그렇다면 어떻게?

답변

0

BouncyCastle X509v3CertificateBuilder 클래스 (pkix jar)의 소스 코드를 참조하고 필요에 맞게 조정할 수 있습니다. 이 클래스는 V3TBSCertificateGenerator를 사용하여 TBSCertificate을 생성합니다. 이것은 DER로 인코딩 할 수있는 ASN.1 객체입니다. 그런 다음 "암호화 시스템"에 의해 서명 된 DER 인코딩을 얻을 수 있습니다. 그런 다음 TBS 인증서와 서명을 최종 X.509 인증서에 넣는 방법에 관해서는 X509v3CertificateBuilder.build() 메서드를 참조하십시오.

0

저는 한 가지 방법을 보여주는 예제를 작성했습니다. 이 코드의 대부분은 bouncycastle pkix 또는 lwcrypto 라이브러리에서 도난 당했지만 모든 버그는 거의 확실합니다. 아래에 집중하는 가장 중요한 방법은 generateCert입니다. 나머지 코드는 테스트를 수행하는 테스트 장치입니다.

이 코드는 특별히 bounycastle bcpkix 및 lwcrypto jars 만 필요로 작성되었습니다. lwcrypto 대신 bcprov jar를 사용하면 다소 단축 될 수 있습니다.

import org.bouncycastle.asn1.ASN1EncodableVector; 
import org.bouncycastle.asn1.DERBitString; 
import org.bouncycastle.asn1.DERSequence; 
import org.bouncycastle.asn1.x500.X500Name; 
import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 
import org.bouncycastle.asn1.x509.TBSCertificate; 
import org.bouncycastle.cert.X509CertificateHolder; 
import org.bouncycastle.cert.bc.BcX509v3CertificateBuilder; 
import org.bouncycastle.crypto.params.RSAKeyParameters; 
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; 
import org.bouncycastle.operator.ContentSigner; 
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; 
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; 
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; 

import javax.security.auth.x500.X500Principal; 
import java.io.ByteArrayInputStream; 
import java.math.BigInteger; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.PublicKey; 
import java.security.cert.CertificateFactory; 
import java.security.cert.X509Certificate; 
import java.security.interfaces.RSAPrivateCrtKey; 
import java.security.interfaces.RSAPublicKey; 
import java.util.Date; 

public class Main { 

    private static class TBSCertPlusSignature { 
     private final byte[] encodedTbsCert; 
     private final byte[] signature; 

     public TBSCertPlusSignature(byte[] encodedTbsCert, byte[] signature) { 
      this.encodedTbsCert = encodedTbsCert; 
      this.signature = signature; 
     } 

     public byte[] getEncodedTbsCert() { 
      return encodedTbsCert; 
     } 

     public byte[] getSignature() { 
      return signature; 
     } 
    } 

    private static TBSCertPlusSignature makeTestCert(KeyPair keyPair) throws Exception { 
     Date now = new Date(); 
     Date nowPlus1Hour = new Date(now.getTime() + 1000 * 60 * 60 * 1L); 
     byte[] encodedName = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").getEncoded(); 
     X500Name issuer = X500Name.getInstance(encodedName); 
     X500Name subject = issuer; 
     RSAPublicKey rsaPub = (RSAPublicKey) keyPair.getPublic(); 
     RSAKeyParameters rsaPubParams = new RSAKeyParameters(false, rsaPub.getModulus(), rsaPub.getPublicExponent()); 
     BcX509v3CertificateBuilder certBuilder = new BcX509v3CertificateBuilder(
       issuer, 
       BigInteger.valueOf(100L), 
       now, 
       nowPlus1Hour, 
       subject, 
       rsaPubParams 
     ); 


     AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSA"); 
     AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); 
     RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) keyPair.getPrivate(); 
     RSAPrivateCrtKeyParameters rsaPrivParams = new RSAPrivateCrtKeyParameters(
       rsaPriv.getModulus(), 
       rsaPriv.getPublicExponent(), 
       rsaPriv.getPrivateExponent(), 
       rsaPriv.getPrimeP(), 
       rsaPriv.getPrimeQ(), 
       rsaPriv.getPrimeExponentP(), 
       rsaPriv.getPrimeExponentQ(), 
       rsaPriv.getCrtCoefficient() 
     ); 

     ContentSigner contentSigner = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(rsaPrivParams); 
     final X509CertificateHolder x509CertificateHolder = certBuilder.build(contentSigner); 
     byte[] tbsCertDER = x509CertificateHolder.toASN1Structure().getTBSCertificate().getEncoded(); 
     byte[] signature = x509CertificateHolder.getSignature(); 
     return new TBSCertPlusSignature(tbsCertDER, signature); 
    } 


    private static X509Certificate generateCert(byte[] tbsCertEncoded, byte[] signature) throws Exception { 
     // Given the der encoded TBS cert and signature, create the corresponding X509 certificate 

     TBSCertificate tbsCert = TBSCertificate.getInstance(tbsCertEncoded); 

     ASN1EncodableVector v = new ASN1EncodableVector(); 

     v.add(tbsCert); 
     v.add(tbsCert.getSignature()); 
     v.add(new DERBitString(signature)); 

     DERSequence derSequence = new DERSequence(v); 
     ByteArrayInputStream baos = new ByteArrayInputStream(derSequence.getEncoded()); 
     return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(baos); 
    } 


    public static void main(String[] args) throws Exception { 

     KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(1024); 
     KeyPair keyPair = kpg.generateKeyPair(); 

     TBSCertPlusSignature testData = makeTestCert(keyPair); 

     X509Certificate x509Cert = generateCert(testData.getEncodedTbsCert(), testData.getSignature()); 

     // Verify the signature 

     x509Cert.verify(keyPair.getPublic()); 

     // Print the cert 

     PublicKey publicKey = x509Cert.getPublicKey(); 
     System.out.println(x509Cert); 

    } 
} 
관련 문제