|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--com.dstc.security.cms.CMSSignature
A class for signing data according to RFC 2630 "Cryptographic Message Syntax" and for verifying data signed according to that specification.
Both RSA and DSA public key algorithms are supported. The message digest algorithm SHA-1 is supported (and recommended) for both RSA and DSA. For RSA, the MD5 digest algorithm is also supported. A signer must possess both the private key and the accompanying X.509 certificate, and preferably the whole certificate chain up to but not including the root CA certificate. The certificate (sub)chain that is used to initialize an SMIMESignature instance for signing is carried in the signed message.
In this release, verification of multiply-signed data is supported but signing already signed data is not.
The data to be signed can be encapsulated (or not) in the CMS signed data, and may be itself signed or encrypted data.
CMS supports inclusion of arbitrary "attributes" in the signing
process. Signing with attributes is enabled by default with the attributes
content type, message digest and signing time included.
Signing without attributes is also supported and is enabled by
setting the system property jcsi.cms.nosignedatts
to
true
. Verification of
data signed with and without attributes are both supported.
Example usage:
//////// Signing /////////// // Some data to be signed, available as an InputStream InputStream data = .... // Wrap with a CMSTypedDataInputStream CMSTypedDataInputStream cis = new CMSTypedDataInputStream(data); // a private key for a signer "Joe" PrivateKey joePrivateKey = ... // the corresponding chain of X.509 certificates for "Joe" X509Certicate joeCert = .... X509Certicate intermediateCACert = .... X509Certicate rootCACert = .... // Initializes a CMSSignature for signing by "Joe" // with "SHA-1" as the message digest algorithm // and the certificate chain up to but not including the root CA // certificate. // NB: The chain must begin with the end-user certificate CMSSignature sig = new CMSSignature(); sig.initSign(joePrivateKey, new X509Certificate[]{joeCert, intermediateCACert}, "SHA-1"; // Sets the data to sign with encapsulation sig.setDataToBeSigned(cis, true); // Sign it CMSTypedDataInputStream signed = sig.sign(); // Read signed data from stream .... //////// Verification //////// // A verifying party obtains the signed data and instantiates it // as an InputStream InputStream fromJoe = ....... // Obtains a trustedCerts Vector including "Joe"'s root CA cert. // The root CA cert is obtained out-of-bands, eg. from the CA // itself Vector trustedCerts = ... // Initializes a CMSSignature instance for verification // with the trustedCerts. and a null cert store // NB: A non-null cert store is required if there are "missing" // intermediate CA certs, eg. if "Joe" had only included his // end-user certificate in the signing process. CMSSignature sig = new CMSSignature(); sig.initVerify(trustedCerts, null); // Sets the data to verify sig.setDataToBeVerified(fromJoe) // ... verifies it VerificationResult res = sig.verify(); // ... obtains the data that was signed as an InputStream CMSTypedDataInputStream verified = res.getVerified(); // ... and reads data from the stream .........
CMSTypedDataInputStream
,
VerificationResult
,
SignedData
,
SMIMESignature
Constructor Summary | |
CMSSignature()
Default constructor |
Method Summary | |
void |
initSign(PrivateKey priv,
X509Certificate[] certChain,
String digestAlg)
Initializes for signing of one or more pieces of data with a PrivateKey, its associated certificate chain and a digest algorithm. |
void |
initVerify(Vector trusted,
Vector store)
Initializes for verification of one or more CMS signed data instances with a Vector of trusted certificates (trust anchors) and, optionally, a supplementary certificate store. |
void |
setDataToBeSigned(CMSTypedDataInputStream in,
boolean encapContent)
Supplies the data to be signed in the form of a CMSTypedDataInputStream from which it can be read, together with an indication of whether it should be encapsulated in the subsequently generated CMS signed data. |
void |
setDataToBeVerified(InputStream in)
Supplies the CMS signed data for verification as an InputStream from which it can be read. |
void |
setDataToBeVerified(InputStream in,
InputStream msg)
Supplies the CMS signed data for verification as an InputStream from which it can be read together with an InputStream for the signed content. |
CMSTypedDataInputStream |
sign()
Signs the previously supplied data and returns a CMSTypedDataInputStream from which the CMS signed data can be read. |
VerificationResult |
verify()
Verifies the previously supplied CMS signed data and returns a VerificationResult. |
Methods inherited from class java.lang.Object |
clone,
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
toString,
wait,
wait,
wait |
Constructor Detail |
public CMSSignature()
Method Detail |
public void initVerify(Vector trusted, Vector store) throws CMSException
The trusted certificates are typically root CA certificates (but may include non-root certificates) which the user trusts explicitly. The optional certificate store is used in certificate path validation when intermediate CA certificates (or even user certificates) are not carried in the signed data.
trusted
- non-null list of trust anchorsstore
- optional (may be null) certificate store
for certificate path validationpublic void initSign(PrivateKey priv, X509Certificate[] certChain, String digestAlg) throws CMSException
The private key must be either an RSA or a DSA PrivateKey. The certificate chain must begin with the user (or end-entity) certificate and must be of length at least 1. The user certificate must be such that it allows signing. The certificate chain that is included will be carried in the CMS signed data that is subsequently generated. Current practice is to include the chain up to (but not including) a root certificate. If the private key algorithm is "RSA", the supplied digest algorithm must be either "SHA" or "MD5". If it is "DSA" the supplied digest algorithm must be "SHA"
priv
- User private key used for signingcertChain
- Associated certificate chain beginning with the
user certificate and one length at least 1digestAlg
- Message digest algorithmpublic void setDataToBeSigned(CMSTypedDataInputStream in, boolean encapContent) throws CMSException
The data to be signed can itself be CMS signed or encrypted data
(for instance, obtained from an encrypt()
to
CMSCipher
), thereby allowing arbitrarily nested CMS data.
If the data to be signed is not encapsulated, it must be transferred separately to the verifying partythe verifying party.
in
- data to be signedencapContent
- true if content is to be encapsulated in the CMS
signed data to be generated and false otherwise.public void setDataToBeVerified(InputStream in) throws CMSException
The supplied enveloped data is expected to have the signed
content encapsulated. Otherwise, a CMSException will be thrown
during verification. It is usually known from the context whether
content is encapsulated. If there is no encapsulation, the two-parameter
setDataToBeVerified()
method needs to be called instead.
in
- InputStream from which the CMS signed data to verify
is to be readpublic void setDataToBeVerified(InputStream in, InputStream msg) throws CMSException
This method is to be called when the CMS signed data does not have encapsulated content, requiring it to be supplied separately. It is usually known from the context whether content is encapsulated or not. If the content is encapsulated the separately supplied content will be ignored during verification.
in
- InputStream from which the CMS signed data to verify
can be readmsg
- InputStream from which the content to verify against
can be readpublic VerificationResult verify() throws CMSException, IOException
In JCSI's default mode of operation, verification is successful if an instance of VerificationResult is returned as a result of this call. Data that is read from the InputStream associated with this VerificationResult can be considered "verified". However, the signature verification process is such that the data purported to be signed will have had to have been read and buffered so that it can be subsequently returned, with obvious memory implications if the amount of data signed is large.
In order to support one-pass processing without data buffering
for memory-sensitive applications, JCSI supports a second mode of operation
(enabled by setting the system property
jcsi.cms.delayverify=true
)
in which actual verification is delayed until reading till end-of-file
from the InputStream obtained by getVerified() followed by a
call to getCMSSignedData(). In other words, data read from the
InputStream is not "verified" and
After this call, the state is reset to what it was in right after the last call to initVerify().
public CMSTypedDataInputStream sign() throws CMSException, IOException
By default, signed attributes (message digest, content type and
signing time) will be
included in the CMS signed data. If signed attributes are
required jcsi.cms.nosignedatts
must be set to
true
.
NB: Actual signing is triggered by the caller of read()
on the returned InputStream
, to avoid having to buffer
the message to be signed. Therefore, the actual signing time will lie
between the first call to read()
and when eof is reached.
After this call, the state is reset to what it was in right after the last call to initSign().
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |