pkcs7signeddata.java

来自「bouncycastle 是一个JAVA安全提供者」· Java 代码 · 共 599 行 · 第 1/2 页

JAVA
599
字号
package org.bouncycastle.jce;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.math.BigInteger;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.Signature;import java.security.SignatureException;import java.security.cert.CRL;import java.security.cert.CRLException;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.cert.X509CRL;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.Collection;import java.util.Enumeration;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import org.bouncycastle.asn1.*;import org.bouncycastle.asn1.pkcs.ContentInfo;import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber;import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;import org.bouncycastle.asn1.pkcs.SignedData;import org.bouncycastle.asn1.pkcs.SignerInfo;import org.bouncycastle.asn1.x509.AlgorithmIdentifier;import org.bouncycastle.asn1.x509.CertificateList;import org.bouncycastle.asn1.x509.X509CertificateStructure;import org.bouncycastle.asn1.x509.X509Name;import org.bouncycastle.jce.provider.X509CRLObject;import org.bouncycastle.jce.provider.X509CertificateObject;/** * Represents a PKCS#7 object - specifically the "Signed Data" * type. * <p> * How to use it? To verify a signature, do: * <pre> * PKCS7SignedData pkcs7 = new PKCS7SignedData(der_bytes);        // Create it * pkcs7.update(bytes, 0, bytes.length);                          // Update checksum * boolean verified = pkcs7.verify();                             // Does it add up? * * To sign, do this: * PKCS7SignedData pkcs7 = new PKCS7SignedData(privKey, certChain, "MD5"); * pkcs7.update(bytes, 0, bytes.length);                          // Update checksum * pkcs7.sign();                                                  // Create digest * * bytes = pkcs7.getEncoded();                                    // Write it somewhere * </pre> * <p> * This class is pretty close to obsolete, for a much better (and more complete) * implementation of PKCS7 have a look at the org.bouncycastle.cms package. */public class PKCS7SignedData    implements PKCSObjectIdentifiers{    private int version, signerversion;    private Set digestalgos;    private Collection certs, crls;    private X509Certificate signCert;    private byte[] digest;    private String digestAlgorithm, digestEncryptionAlgorithm;    private Signature sig;    private transient PrivateKey privKey;    private final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1";    private final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2";    private final String ID_MD5 = "1.2.840.113549.2.5";    private final String ID_MD2 = "1.2.840.113549.2.2";    private final String ID_SHA1 = "1.3.14.3.2.26";    private final String ID_RSA = "1.2.840.113549.1.1.1";    private final String ID_DSA = "1.2.840.10040.4.1";    /**     * Read an existing PKCS#7 object from a DER encoded byte array using     * the BC provider.     */    public PKCS7SignedData(        byte[]  in)        throws SecurityException, CRLException, InvalidKeyException,        CertificateException, NoSuchProviderException, NoSuchAlgorithmException    {        this(in, "BC");    }    /**     * Read an existing PKCS#7 object from a DER encoded byte array      */    public PKCS7SignedData(        byte[]  in,        String  provider)        throws SecurityException, CRLException, InvalidKeyException,        CertificateException, NoSuchProviderException, NoSuchAlgorithmException    {        ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream(in));        //        // Basic checks to make sure it's a PKCS#7 SignedData Object        //        DERObject pkcs;        try        {            pkcs = din.readObject();        }        catch (IOException e)        {            throw new SecurityException("can't decode PKCS7SignedData object");        }        if (!(pkcs instanceof ASN1Sequence))        {            throw new SecurityException("Not a valid PKCS#7 object - not a sequence");        }        ContentInfo content = ContentInfo.getInstance(pkcs);        if (!content.getContentType().equals(signedData))        {            throw new SecurityException("Not a valid PKCS#7 signed-data object - wrong header " + content.getContentType().getId());        }        SignedData  data = SignedData.getInstance(content.getContent());        certs = new ArrayList();        if (data.getCertificates() != null)        {            Enumeration ec = ASN1Set.getInstance(data.getCertificates()).getObjects();            while (ec.hasMoreElements())            {                certs.add(new X509CertificateObject(X509CertificateStructure.getInstance(ec.nextElement())));            }        }        crls = new ArrayList();        if (data.getCRLs() != null)        {            Enumeration ec = ASN1Set.getInstance(data.getCRLs()).getObjects();            while (ec.hasMoreElements())            {                crls.add(new X509CRLObject(CertificateList.getInstance(ec.nextElement())));            }        }        version = data.getVersion().getValue().intValue();        //        // Get the digest algorithm        //        digestalgos = new HashSet();        Enumeration e = data.getDigestAlgorithms().getObjects();        while (e.hasMoreElements())        {            ASN1Sequence s = (ASN1Sequence)e.nextElement();            DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0);            digestalgos.add(o.getId());        }        //        // Get the SignerInfo        //        ASN1Set signerinfos = data.getSignerInfos();        if (signerinfos.size() != 1)        {            throw new SecurityException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time");        }        SignerInfo signerInfo = SignerInfo.getInstance(signerinfos.getObjectAt(0));        signerversion = signerInfo.getVersion().getValue().intValue();        IssuerAndSerialNumber isAnds = signerInfo.getIssuerAndSerialNumber();        //        // Get the signing certificate        //        BigInteger      serialNumber = isAnds.getCertificateSerialNumber().getValue();        X509Principal   issuer = new X509Principal(isAnds.getName());        for (Iterator i = certs.iterator();i.hasNext();)        {            X509Certificate cert = (X509Certificate)i.next();            if (serialNumber.equals(cert.getSerialNumber())                    && issuer.equals(cert.getIssuerDN()))            {                signCert = cert;                break;            }        }        if (signCert == null)        {            throw new SecurityException("Can't find signing certificate with serial "+serialNumber.toString(16));         }        digestAlgorithm = signerInfo.getDigestAlgorithm().getObjectId().getId();        digest = signerInfo.getEncryptedDigest().getOctets();        digestEncryptionAlgorithm = signerInfo.getDigestEncryptionAlgorithm().getObjectId().getId();        sig = Signature.getInstance(getDigestAlgorithm(), provider);        sig.initVerify(signCert.getPublicKey());    }    /**     * Create a new PKCS#7 object from the specified key using the BC provider.     *     * @param privKey the private key to be used for signing.     * @param certChain the certificate chain associated with the private key.     * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"     */    public PKCS7SignedData(        PrivateKey      privKey,        Certificate[]   certChain,        String          hashAlgorithm)        throws SecurityException, InvalidKeyException,        NoSuchProviderException, NoSuchAlgorithmException    {        this(privKey, certChain, hashAlgorithm, "BC");    }    /**     * Create a new PKCS#7 object from the specified key.     *     * @param privKey the private key to be used for signing.     * @param certChain the certificate chain associated with the private key.     * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"     * @param provider the provider to use.     */    public PKCS7SignedData(        PrivateKey      privKey,        Certificate[]   certChain,        String          hashAlgorithm,        String          provider)        throws SecurityException, InvalidKeyException,        NoSuchProviderException, NoSuchAlgorithmException    {        this(privKey, certChain, null, hashAlgorithm, provider);    }    /**     * Create a new PKCS#7 object from the specified key.     *     * @param privKey the private key to be used for signing.     * @param certChain the certificate chain associated with the private key.     * @param crlList the crl list associated with the private key.     * @param hashAlgorithm the hashing algorithm used to compute the message digest. Must be "MD5", "MD2", "SHA1" or "SHA"     * @param provider the provider to use.     */    public PKCS7SignedData(        PrivateKey      privKey,        Certificate[]   certChain,        CRL[]           crlList,        String          hashAlgorithm,        String          provider)        throws SecurityException, InvalidKeyException,        NoSuchProviderException, NoSuchAlgorithmException    {        this.privKey = privKey;        if (hashAlgorithm.equals("MD5"))        {            digestAlgorithm = ID_MD5;        }        else if (hashAlgorithm.equals("MD2"))        {            digestAlgorithm = ID_MD2;        }        else if (hashAlgorithm.equals("SHA"))        {            digestAlgorithm = ID_SHA1;        }        else if (hashAlgorithm.equals("SHA1"))        {            digestAlgorithm = ID_SHA1;        }        else        {            throw new NoSuchAlgorithmException("Unknown Hash Algorithm "+hashAlgorithm);        }        version = signerversion = 1;        certs = new ArrayList();        crls = new ArrayList();        digestalgos = new HashSet();        digestalgos.add(digestAlgorithm);        //

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?