Java in a Nutshell, 5th Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java in a Nutshell, 5th Edition [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


5.15. Security




The java.security
package defines quite a few classes related to the Java
access-control architecture, which is discussed in more detail in
Chapter 6. These classes allow Java programs to
run untrusted code in a restricted environment from which it can do
no harm. While these are important classes, you rarely need to use
them. The more interesting classes are the ones used for message
digests and digital signatures; they are demonstrated in the sections
that follow.


5.15.1. Message Digests


A

message digest
is a value, also known as cryptographic checksum or secure hash, that
is computed over a sequence of bytes. The length of the digest is
typically much smaller than the length of the data for which it is
computed, but any change, no matter how small, in the input bytes
produces a change in the digest. When transmitting data (a message),
you can transmit a message digest along with it. The recipient of the
message can then recompute the message digest on the received data
and, by comparing the computed digest to the received digest,
determine whether the message or the digest was corrupted or tampered
with during transmission. We saw a way to compute a message digest
earlier in the chapter when we discussed streams. A similar technique
can be used to compute a message digest for nonstreaming binary data:

import java.security.*;
// Obtain an object to compute message digests using the "Secure Hash
// Algorithm"; this method can throw a NoSuchAlgorithmException.
MessageDigest md = MessageDigest.getInstance("SHA");
byte[] data, data1, data2, secret; // Some byte arrays initialized elsewhere
// Create a digest for a single array of bytes
byte[] digest = md.digest(data);
// Create a digest for several chunks of data
md.reset(); // Optional: automatically called by digest()
md.update(data1); // Process the first chunk of data
md.update(data2); // Process the second chunk of data
digest = md.digest(); // Compute the digest
// Create a keyed digest that can be verified if you know the secret bytes
md.update(data); // The data to be transmitted with the digest
digest = md.digest(secret); // Add the secret bytes and compute the digest
// Verify a digest like this
byte[] receivedData, receivedDigest; // The data and the digest we received
byte[] verifyDigest = md.digest(receivedData); // Digest the received data
// Compare computed digest to the received digest
boolean verified = java.util.Arrays.equals(receivedDigest, verifyDigest);


5.15.2. Digital Signatures



A

digital
signature combines a message-digest algorithm with public-key
cryptography. The sender of a message, Alice, can compute a digest
for a message and then encrypt that digest with her private key. She
then sends the message and the encrypted digest to a recipient, Bob.
Bob knows Alice's public key (it is public, after
all), so he can use it to decrypt the digest and verify that the
message has not been tampered with. In performing this verification,
Bob also learns that the digest was encrypted with
Alice's private key since he was able to decrypt the
digest successfully using Alice's public key. As
Alice is the only one who knows her private key, the message must
have come from Alice. A digital signature is called such because,
like a pen-and-paper signature, it serves to authenticate the origin
of a document or message. Unlike a pen-and-paper signature, however,
a digital signature is very difficult, if not impossible, to forge,
and it cannot simply be cut and pasted onto another document.

Java makes creating digital signatures easy. In order to create a
digital signature, however, you need a
java.security.PrivateKey object. Assuming that a
keystore exists on your system (see the

keytool
documentation in Chapter 8), you can get one
with code like the following:

// Here is some basic data we need
File homedir = new File(System.getProperty("user.home"));
File keyfile = new File(homedir, ".keystore"); // Or read from config file
String filepass = "KeyStore password" // Password for entire file
String signer = "david"; // Read from config file
String password = "No one can guess this!"; // Better to prompt for this
PrivateKey key; // This is the key we want to look up from the keystore
try {
// Obtain a KeyStore object and then load data into it
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(new BufferedInputStream(new FileInputStream(keyfile)),
filepass.toCharArray());
// Now ask for the desired key
key = (PrivateKey) keystore.getKey(signer, password.toCharArray());
}
catch (Exception e) { /* Handle various exception types here */ }

Once you have a PrivateKey object, you can create
a digital signature with a java.security.Signature
object:

PrivateKey key;             // Initialized as shown previously
byte[] data; // The data to be signed
Signature s = // Obtain object to create and verify signatures
Signature.getInstance("SHA1withDSA"); // Can throw a
// NoSuchAlgorithmException
s.initSign(key); // Initialize it; can throw an InvalidKeyException
s.update(data); // Data to sign; can throw a SignatureException
/* s.update(data2); */ // Call multiple times to specify all data
byte[] signature = s.sign(); // Compute signature

A Signature object can verify a digital signature:

byte[] data;        // The signed data; initialized elsewhere
byte[] signature; // The signature to be verified; initialized elsewhere
String signername; // Who created the signature; initialized elsewhere
KeyStore keystore; // Where certificates stored; initialize as shown earlier
// Look for a public-key certificate for the signer
java.security.cert.Certificate cert = keystore.getCertificate(signername);
PublicKey publickey = cert.getPublicKey(); // Get the public key from it
Signature s = Signature.getInstance("SHA1withDSA"); // Or some other algorithm
s.initVerify(publickey); // Setup for verification
s.update(data); // Specify signed data
boolean verified = s.verify(signature); // Verify signature data


5.15.3. Signed Objects




The
java.security.SignedObject class is a convenient
utility for wrapping a digital signature around an
object. The
SignedObject can then be serialized and
transmitted to a recipient, who can deserialize it and use the
verify( ) method to verify the signature:

Serializable o;  // The object to be signed; must be Serializable
PrivateKey k; // The key to sign with; initialized elsewhere
Signature s = Signature.getInstance("SHA1withDSA"); // Signature "engine"
SignedObject so = new SignedObject(o, k, s); // Create the SignedObject
// The SignedObject encapsulates the object o; it can now be serialized
// and transmitted to a recipient.
// Here's how the recipient verifies the SignedObject
SignedObject so; // The deserialized SignedObject
Object o; // The original object to extract from it
PublicKey pk; // The key to verify with
Signature s = Signature.getInstance("SHA1withDSA"); // Verification "engine"
if (so.verify(pk,s)) // If the signature is valid,
o = so.getObject(); // retrieve the encapsulated object.


/ 1191