📄 pkcs7signeddata.java
字号:
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
{
DERInputStream din = new DERInputStream(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 the private key to be used for signing.
* @param the certifiacate 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -