向证书添加签名 [英] Adding a signature to a certificate

查看:88
本文介绍了向证书添加签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须忍受一些奇怪的要求.我需要通过密码系统的TBS证书,他们将对其进行签名并发回签名字符串,我需要将其合并到证书中以制成签名证书.

I have some odd requirements that I have to live with. I need to pass my crypto system a TBS certificate, they will sign it and send back a String of the signature which I need to incorporate into a certificate to make a signed certificate.

看看com.ibm.security.x509.X509CertImpl和SO上的各种BouncyCastle帖子,我不知道该怎么做.

Looking at com.ibm.security.x509.X509CertImpl and various BouncyCastle posts on SO, I can't find out how to do that.

问题:

这可能吗?如果是这样,怎么办?

Is this possible ? If so, how ?

推荐答案

我整理了一个示例,展示了一种实现方法.大部分代码是从bouncycastle pkix或lwcrypto库中窃取的,但是几乎可以肯定所有错误都是我的.下面重点介绍的最重要方法是 generateCert .其余代码是测试工具,可以驱动测试.

I've put together an example that shows one way to do it. Most of this code was stolen from the bouncycastle pkix or lwcrypto libraries, but any bugs are almost certainly mine. The most important method to concentrate on below is generateCert. The rest of the code is test harness to drive the test.

专门为仅使用bounycastle bcpkix和lwcrypto jars编写的代码.如果使用bcprov jar而不是lwcrypto,则可以将其缩短.

The code is specifically written to need only the bounycastle bcpkix and lwcrypto jars. It could be shortened somewhat if the bcprov jar was used instead of lwcrypto.

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

    }
}

这篇关于向证书添加签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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