2016-09-27 4 views
0

У меня есть некоторые странные требования, с которыми мне нужно жить. Мне нужно передать мою криптосистему сертификат TBS, они подпишут его и отправят обратно строку подписи, которую мне нужно включить в сертификат, чтобы сделать подписанный сертификат.Добавление подписи к сертификату

Глядя на com.ibm.security.x509.X509CertImpl и различные сообщения BouncyCastle на SO, я не могу узнать, как это сделать.

Вопросы:

возможно ли это? Если да, то как?

ответ

0

Я бы назвал исходный код класса BouncyCastle X509v3CertificateBuilder (pkix jar) и настроил его в соответствии с вашими потребностями. Обратите внимание, что этот класс использует V3TBSCertificateGenerator для получения TBSCertificate. Это объект ASN.1, который вы можете кодировать DER. Затем вы можете получить кодировку DER, подписанную «криптосистемой». Затем обратитесь к методу X509v3CertificateBuilder.build() о том, как сдать сертификат TBS и подпись вместе в окончательный сертификат X.509.

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); 

    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^