SignedObjectpublic class SignedObject extends Object implements SerializableA SignedObject is exactly that--an object that bears a digital signature.
Subclass this class to add a digital signature to any class you want.
Note, however, that the signature is computed using serialization, so only
the serializable, non-transient fields of a subclass are included in
the signature computation. |
Fields Summary |
---|
protected String | signername | protected String | algorithm | private byte[] | signature | private transient boolean | signing |
Methods Summary |
---|
public void | removeSignature()When the contents of the object change, the signature becomes invalid.
When this happens, the signature should be erased, because validation
is guaranteed to fail.
signature = null; signername = null; algorithm = null;
| public synchronized void | sign(java.lang.String signername, java.lang.String algorithm)This method computes a digital signature for the current state of the
object, excluding the signature-related state of this class.
That is, the signature is based only on the state of the subclasses.
The arguments specify who is signing the object, and what digital
signature algorithm to use.
Note that no other threads should be modifying the object while
this computation is being performed. If a subclass will be used in a
multi-threaded environment, this means that methods of the subclass
that modify its state should be synchronized like this one is. // A flag used below.
// Save the arguments for use by verify()
this.signername = signername;
this.algorithm = algorithm;
// Get a Signature object to compute the signature with
Signature s = Signature.getInstance(algorithm);
// Get a Signer object representing the signer
Signer signer =
(Signer)IdentityScope.getSystemScope().getIdentity(signername);
// Initialize the Signature object using the PrivateKey of the Signer
s.initSign(signer.getPrivateKey());
// Create an ObjectOutputStream that writes its output to a
// ByteArrayStream. This is how we capture the state of the object
// so that it can be signed.
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
// Now serialize the object, capturing its state. We have to set a flag
// before we do this, so that the signer name, algorithm, and signature
// itself are not included in this serialized state. See writeObject()
// below to see how this works.
signing = true;
out.writeObject(this);
signing = false;
// Now tell the Signature object about the bytes of serialized state
// that were stored by the ByteArrayOutputStream
s.update(bout.toByteArray());
// And finally, compute the signature
this.signature = s.sign();
| public synchronized void | sign(java.lang.String signername)A simpler version of sign(), that defaults to using the DSA algorithm
sign(signername, "DSA");
| public synchronized boolean | verify()This method verifies the signature of any SignedObject subclass.
It works much like the sign() method, and is also synchronized.
// Make sure the object is actually signed.
if (signature == null)
throw new SignatureException("Object is not signed");
// Get the signature, signer and public key, and initialize, like above,
// except that this time use a PublicKey instead of a PrivateKey
Signature s = Signature.getInstance(algorithm);
Identity signer =
(Identity)IdentityScope.getSystemScope().getIdentity(signername);
s.initVerify(signer.getPublicKey());
// Create streams and capture the current state of the object
// (excluding the signature bytes themselves) in a byte array
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
signing = true;
out.writeObject(this);
signing = false;
// Pass state of the object to the Signature, and verify the stored
// signature bytes against that state. Return the result of verification.
s.update(bout.toByteArray());
return s.verify(this.signature);
| private void | writeObject(java.io.ObjectOutputStream out)This method is invoked to allow custom serialization.
We only write out our signature-related state when we are not computing
or verifying a signature. When we are computing or verifying, only our
subclass state gets written out. If we don't do this, verification will
fail because the signature[] array will obviously be different on
verification than it is when the signature is generated.
if (!signing) out.defaultWriteObject();
|
|