Java Cryptography Programming ( PDFDrive )
Java Cryptography Programming ( PDFDrive )
1
The aim of the Java Cryptography Architecture (JCA) is to let
API users use cryptographic services without concern for the
implementations or even the algorithms.
JCA encompasses the parts of the Java 2 SDK Security API, also
covers the Java Cryptography Extension (JCE).
JCA uses a provider-based architecture. A provider in JCA means
a Cryptographic Service Provider (CSP), witch is a package or set
of packages that implement JCA services, such as digital signature
algorithms, message digest algorithms, etc.
2
Each SDK installation has one or more provider packages installed,
and users may add new providers. Users may configure their
runtime with different providers and specify a preference order for
each.
JCA offers a set of APIs that allows users to query which providers
are installed and what services they support.
3
JCA architecture
Application
API
java.security.Security
Signature Cipher
MessageDigest KeyAgreement
KeyPairGenerator Keygenerator
KeyFactory SecretKeyFactory
AlgorithmParameterGenerator MAC
AlgorithmParameters
SPI
↑↑↑↑↑↑↑↑↑↑
CSP1 CSP2 CSP3
4
A cryptographic engine class defines a cryptographic service in an
abstract fashion without a concrete implementation. A engine, or
service, is always associated with a particular algorithm or type
and does one of the following:
• Provides cryptographic operations (digital signature, message
digest, etc)
• Generates or supplies the cryptographic material (keys,
parameters, etc)
• Generates data objects (keystores, certificates, etc.)
5
A generator and a factory differ within the JCA context. A
generator creates objects with new contents, whereas a factory
creates objects from existing materials (e.g., an encoding).
An engine class provides the interface to the functionality of a
specific type of service, independent of a particular cryptographic
algorithm (provides APIs). The implementations, from one or more
providers, are those for specific algorithms.
6
The application interfaces supplied by an engine class are
implemented in a Service Provider Interface (SPI). That is, for each
engine class, there is a corresponding abstract SPI class that
defines the SPI methods that cryptographic service provider must
implement.
Implementations for various cryptography services are provided by
JCA provider (JSP) such as SUN and SunJCE providers. Other
providers may define their own implementations of those services or
of other services not implemented by these providers.
7
For examples, the SPI class corresponding to the Signature engine
class is the SinatureSpi class. Each SPI class is abstract. To
supply the implementation of a particular type of service, for a
specific algorithm, a provider must subclass the corresponding SPI
class and provide implementations for all the abstract methods.
http://download.oracle.com/javase/1.4.2/docs/guide/security/
8
java.security.Security manages installed providers and security
properties. It contains only static methods and is never
instantiated:
public static Provider[] getProviders()
public static Provider getProvider(String name)
public static int addProvider(Provider provider)
public static int insertProviderAt(Provider provider,
int position)
public static void removeProvider(String name)
public static String getProperty(String key)
public static void setProperty(String key, String datum)
9
getProviders returns an array containing all the installed
providers in their preference order.
The Security class maintains a list of systemwide secutity
properties. These properties are accessible and settable via the
getProperty, setProperty.
The term “provider” refers to a package or set of packages that
supplies a concrete implementation of a subset of cryptography
aspects of the Java 2 SDK security API. The
java.security.Provider class is the interface to such a package
or set of packages. To supply implementation of cryptographic
services, one writes the implementation code and creates a subclass
of the Provider class.
You can query the instance of provider about information using
public String getName(), public double getVersion(),
public String getInfo()
10
The java.security.MessageDigest class.
To compute a digest, first create a MessageDigest instant. A
particular type of message digest algorithm is obtained by calling a
getInstance static factory method. For example,
public static MessageDigest getInstance("SHA-1")
To calculate the digest of some data, supply the data to the
initialized message digest object by calling update methods:
public void update(byte[] input, int offset, int len
public void update(byte[] input)
11
Then compute the digest by call the digest methods:
public byte[] digest()
public byte[] digest(byte[] input)
public int digest(byte[] buf, int offset, int len)
The first two methods return the computed digest. The third
method stores the computed digest in the provided buffer buf,
starting at offset. The len tells the number of bytes in buf
allotted for the digest. The method returns the number of bytes
stored in buf.
The second method is equivalent to making a call to
update(byte[] input).
12
Suppose the message composed three byte arrays: i1, i2, i3.
MessageDigest sha = MessageDigest.getInstance("SHA-1");
sha.update(i1);
sha.update(i2);
sha.update(i3);
byte[] hash = sha.digest();
The call to the digest method signals the end of the input message
and causes the digest to be computed. Or:
sha.update(i1);
sha.update(i2);
byte[] hash = sha.digest(i3);
After the digest has been calculated, the message digest object is
automatically reset and ready to receive new data and calculate its
digest.
13
The java.security.signature class.
The Signature objects are modal objects which is always in one of
the following three states:
1. UNINITIALIZED
2. SIGN
3. VERIFY
To create a signature instance:
public static Signature getInstance(String algorithm)
public static Signature getInstance(String algorithm,
String provider)
A algorithm could be SHA1withDSA, MD5withRSA etc. As a
signature object is created, it is in uninitialized state.
14
To initialize the signature object:
public final void initSign(PrivateKey privateKey) or
public final void initVerify(PublicKey publicKey)
public final void initVerify(Certificate certificate)
To sign or verify a data, use update method to supply the data to
the Signature object. Then call one of the following:
public final byte[] sign()
public final int sign(byte[] outbuf, int offset, int len)
or
public final boolean verify(byte[] signature)
public final boolean verify(byte[] signature, int offset,
int len)
15
An algorithm parameter specification is a transparent
representation of the sets of parameters used with an algorithm.
For example, DSAParameterSpec defines getP, getQ, getG
methods, which access the p, q and g parameters. In an opaque
representation, as supplied by the AlgorithmParameters class, one
has no direct access to the parameters.
AlgorithmParameters.getParameterSpec method can be used to
convert an AlgorithmParameters object to a transparent
specification.
16
java.security.spec.AlgorithmParameterSpec This interface is
the basic interface for the transparent specification of
cryptographic parameters.
java.security.spec.DSAParameterSpec is a class implements the
AlgorithmParameterSpec interfacem specifies the set of
parameters used with DSA. The following methods returns the
DSA algorithm parameter.
public BigInteger getP()
public BigInteger getQ()
public BigInteger getG()
17
java.security.AlgorithmParameters is a engine class providing
an opaque representation of cryptographic parameters. An object
for a particular type of algorithm is obtained by calling one of the
static factory methods:
public static AlgorithmParameters getInstance(String
algorithm)
public static AlgorithmParameters getInstance(String
algorithm, String provider)
public static AlgorithmParameters getInstance(String
algorithm, Provider provider)
Once an AlgorithmParameters object is instantiated, it must be
initialized using an appropriate parameter specification or
parameter encoding.
18
public void init(AlgorithmParameterSpec paramSpec)
public void init(byte[] params)
public void init(byte[] params, String format)
The params is an array containing the encoded parameters and
format is the name of the decoding format. The primary decoding
format is ASN.1. An AlgorithmParameters objects may be
initialized only once.
public byte[] getEncode() returns the parameters in their
primary encoding format.
public byte[] getEncode(Sting format) returns the
parameters in a specified encoding format.
19
AlgorithmParameterGenerator is an engine class generating a set
of parameters suitable for the algorithm that is specified.
public static AlgorithmParameterGenerator getInstance(
String algorithm)
public static AlgorithmParameterGenerator getInstance(
String algorithm, String provider)
public static AlgorithmParameterGenerator getInstance(
String algorithm, Provider provider)
The object can be initialized in a way of Algorithm independent or
Algorithm specific.
20
The algorithm-independent uses a source of randomness and a size.
The size is interpreted differently for different algorithms. For
example, in the case of DSA algorithm, the size is the prime
modulus, in bit. It can just use the system-provided source of
randomness.
public void init(int size, SecureRandom random)
public void init(int size)
The algorithm-specific initialization:
public void init(AlgorithmParameterSpec genParamSpec,
SecureRandom random)
public void init(AlgorithmParameterSpec genParamSpec)
where a algorithm-specific semantics is represented by a set of
algorithm specific parameters generated values supplied in an
AlgorithmParameterSpec object.
21
Once an AlgorithmParameterGenetator object has been initiated,
the algorithm parameters can be generated by using the method:
public AlgorithmParameter generateParameters()
22
java.security.Key is the top-level interface for opaque keys. In
an opaque key representation, you have no direct access to the key
material. All opaque keys have three characteristics:
1. An algorithm - the key algorithm for that key (DSA, RSA,
MD5withRSA, SHA1withRSA, etc)
2. An encoded form (external encoded form for the key used when
a standard representation of the key is needed outside the
JVM, as when transmitting the key to another party).
3. A format (the format of the encoded key).
These characteristics can be obtained by following methods:
public String getAlgorithm()
public byte[] getEncoded()
public String getFormat()
23
java.security.PublicKey and java.security.PrivateKey are
methodless interfaces both extending the Key interface.
In transparent representation, you can access key-material though
get methods under KeySpec.
The java.security.spec.KeySpec interface contains no methods
or constants. All key specifications must implement this interface.
24
DSAPrivateKeySpec implements the KeySpec interface, specifying
a DSA private key with its associated parameters. The class
contains methods to get private key x and parameters p, q, g.
public BigInteger getX(), public BigInteger getP()
public BigInteger getQ(), public BigInteger getG()
DSAPublicKeySpec implements the KeySpec interface, specifying a
DSA public key with its associated parameters. The class contains
methods to get public key y and parameters p, q, g.
public BigInteger getY(), public BigInteger getP()
public BigInteger getQ(), public BigInteger getG()
25
RSAPrivateKeySpec implements the KeySpec interface, specifying
an RSA private key. The class has methods to return the RSA
modulus n and private exponent a.
public BigInteger getModulus()
public BigInteger getPrivateExponent()
RSAPublicKeySpec implements the KeySpec interface, specifying
an RSA public key. The class has methods to return the RSA
modulus n and public exponent b.
public BigInteger getModulus()
public BigInteger getPublicExponent()
26
EncodedKeySpec implements the KeySpec interface and represents
a public key or private key in encoded format. Methods returns the
encoded key and the name of the encoding format:
public abstract byte[] getEncode()
public abstract String getFormat()
PKCS8EncodedKeySpec is a subclass of EncodedKeySpec
representing the DER encoding of a private key.
X509EncodedKeySpec is a subclass of EncodedKeySpec representing
the DER encoding of a public or private key according to the
format in the X.509 standard.
27
java.security.KeyFactory is an engine class designed to provide
conversions between opaque cryptographic keys of type Key and
key specifications, transparent representations of the underlying
key material.
A KeyFactory object is obtained by calling one of the following:
public static KeyFactory getInstance(String algorithm)
public static KeyFactory getInstance(String algorithm,
String provider)
public static KeyFactory getInstance(String algorithm,
Provider provider)
28
If you have a key specification for a public or private key, you can
obtain an opaque object as follows:
public PublicKey generatePublic(KeySpec keySpec)
public PrivateKey generatePrivate(KeySpec keySpec)
Conversely, if you have a Key objectm you can get a corresponding
KeySpec by calling: public KeySpec getKeySpec(Key key,
Class keySpec)
The keySpec parameter identifies the specification class in which
the key material should be returned. For example,
DSAPublicKeySpec.class.
29
java.security.cert.CertificateFactory is an engine class
which is used to generate certificate and CRL (certificate
revocation list) objects from their encoding.
A certificate factory for X.509 must return certificates that are an
instance of java.security.cert.X509Certificate, and CRLs
that are an instance of java.security.cert.X509CRL.
To create object of CertificateFactory:
Public static CertificateFactory getInstance(String type)
Public static CertificateFactory getInstance(String type,
String provider)
Public static CertificateFactory getInstance(String type,
Provider provider)
30
To generate a Certificate or CRL object and initialize it with the
data read from an input stream, use the method:
public final Certificate generateCertificate(InputStream is)
public final CRL generateCRL(InputStream is)
public final Collection generateCertificates(InputStream is)
public final Collection generateCRLs(InputStream is)
31
The following example reads a file with Base64 encoded certificates,
which are each bounded at the beginning by BEGIN CERTIFICATE,
and bounded at the end by END CERTIFICATE. We convert the
FileInputStream (which does not support mark and reset) to a
BufferedInputStream (which supports those methods).
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
32
The java.security.KeyPair class is a holder for a key pair which
has two methods for returning keys:
public PrivateKey getPrivate()
public PublicKey getPublic()
java.security.KeyPairGenerator is an engine class used to
generate pairs of keys. To create a KeyPairGenerator, use one of
the factory methods:
public static KeypairGenerator getInstance(String algorithm)
public static KeypairGenerator getInstance(String algorithm,
String provider)
public static KeypairGenerator getInstance(String algorithm,
Provider provider)
33
A key pair generator needs to be initialized. In most case,
algorithm-independent initialization is sufficient:
public void initialize(int keysize, SecureRandom random)
public void initialize(int keysize)
In some cases, an algorithm-specific initialization is needed:
public void initialize(AlgorithmParameterSpec params,
SecureRandom random)
public void initialize(AlgorithmParameterSpec params)
To generate a key pair:
public KeyPair generateKeyPair()
34
Example of generate key pair. Initialization:
KeyPairGenerator keyGen =
KeyPairGenerator.getInstance("DSA");
SecurRandom random =
SecureRandom.getInstance("SHA1PRNG","SUN");
random.setSeed(userSeed);
keyGen.initialize(1024,random);
35
If you already have set of DSA-specific parameters p, q and g, then
you can use the following:
KeyPairGenerator keyGen =
KeyPairGenerator.getInstance("DSA");
DSAParameterSpec dsaSpec = new DSAParameterSpec(p,q,g);
SecurRandom random =
SecureRandom.getInstance("SHA1PRNG","SUN");
random.setSeed(userSeed);
keyGen.initialize(1024,random);
Finally, we can generate the key pair.
KeyPair pair = keyGen.generateKeyPair();
36
java.security.KeyStore is an engine class that defines interfaces
to access and modify the information in a keystore.
Two command line tools make use of KeyStore: keytool and
jarsigner, as well as a GUI-based tool, Policy Tool. SDK users
can write additional security applications that use or extend
KeyStore.
Multiple different concrete implementations are possible. For
example, one implementation might provide persistent keystore,
whereas another can use smart cards.
37
A KeySore implementation is provider based. The SDK has a
built-in default implementation, provided by the SUN provider,
that implements the keystore as a file, using a proprietary keystore
type-format-named JKS. The SunJCE provider also includes a
proprietary keystore type named JCEKS, which uses a much
stronger protection of private keys (using password-based
encryption with Triple DES).
KeyStore represents an in-memory collection of keys and
certificates and manages two types of entries: key entries and
trusted certificate entries.
38
To create a KeyStore object, you call the getInstance factory,
specifying the keystore type.
public static KeyStore getInstance(String type)
public static KeyStore getInstance(String type,
String provider)
public static KeyStore getInstance(String type,
Provider provider)
String specifying types are not case sensitive, "jks" will be
considered the same as "JKS".
public final static String getDefaultType() returns the
value of the keystore.type security property, or the default "JKS"
value if no such security property value is defined.
39
Before a KeyStore object can be used, the keystore data must be
loaded into the memory via the following method.
public final void load(InputStream stream, char[]
password)
The optional password is used to check the integrity of the
keystore data. If no password is supplied, no integrity check is
performed. If you want to create an empty keystore, pass null as
the InputStream argument to the method.
Each entry in a keystore is identified by a unique alias. An
enumeration of alias names present in the keystore can be obtained
by:
public final Enumeration aliases()
40
The following methods determine if the entry specified by the given
alias is a key entry or a trusted certificate entry:
public final boolean isKeyEntry(String alias)
public final boolean isCertificateEntry(String alias)
The following method assigns a certificate to a specified alias:
public final void setCertificateEntry(String alias,
Certificate cert)
Similarly, the following method add or set key entries.
public final void setKeyEntry(String alias, byte[] key,
Certificate[] chain)
public final void setKeyEntry(String alias, Key key,
char[] password, Certificate[] chain)
41
To delete an entry:
public final void deleteEntry(String alias)
To return the key associated with the given alias:
public final Key getKey(String alias, char[] password)
The key is recovered by using the password.
To return the certificate, or certificate chain:
public final Certificate getCeritficate(String alias)
public final Certificate[] getCertificateChain(String
alias)
42
To determine the name, or alias, of the first entry whose certificate
matches a given certificate:
public final String getCertificateAlias(Certificate
cert)
To save the in-memory keystore:
public final void store(OutputStream stream, char[]
password)
43
Randomness is very important in cryptography. The basic class of
random-number generator is java.util.Random. Random uses a
seed of 48-bit. If a seed is not assigned explicitly, it is by default a
value based on the time at which the object is create. After the
object has been initialized, various next methods can be called to
obtain the random number in different forms.
The engine class java.security.SecureRandom provides a
cryptographically strong pseudo-random-number generator
(PRNG). This class provides implementation-independent
algorithms. The application can request a particular algorithm
from a specific provider. The default provider SUN supports a
built-in algorithm named SHA1PRNG.
44
To create an instance, it is preferred to use the following:
public static SecureRandom getInstance(String algorithm)
public static SecureRandom getInstance(String algorithm,
String provider)
public static SecureRandom getInstance(String algorithm,
Provider provider)
But public constructors are still provided for backward
compatibility.
public SecureRandom()
public SecureRandom(byte[] seed)
45
The user can explicitly seed the SecureRandom object:
public void setSeed(byte[] seed)
public void setSeed(long seed)
To get random bytes:
public void nextBytes(byre[] bytes)
SecureRandom itself can also help with seed generation (e.g., for
seeding another random object) by calling:
public byte[] generateSeed(int numBytes)
46
javax.crypto.Cipher class provides the functionality of a
cryptographic cipher used for encryption and decryption. This
class forms the core of the JCE framework.
To create a Cipher object, you must specify the transformation
name.
public static Cipher getInstance(String transformation);
public static Cipher getInstance(String transformation,
String provider);
public static Cipher getInstance(String transformation,
Provider provider);
47
A transformation always includes the name of a cryptographic
algorithm, such as DES, and may be followed by a mode and
padding scheme. For examples:
"DES/CBC/PKCSSPadding"
"DES"
If no mode or padding has been specified, provider-specific default
values are used. For example, the SunJCE provider uses ECB as
the default mode and PKCS5padding as the default padding
scheme for DES, DES-EDE (encryption-decryption-encryption),
and blowfish cipher.
48
A Cipher object must be initialized for one of four modes, which
are defined as final integer constants in the Cipher class.
• ENCRYPT MODE
• DECRYPT MODE
• WRAP MODE, for wrapping a Key into bytes so that it can be
securely transported.
• UNWRAP MODE, for unwrapping a previous wrapped key into a
java.security.Key object.
49
To initialize Cipher object, need a mode parameter (opmode), key
or certificate containing the key, algorithm parameters (params),
and a source of randomness (random):
public void init(int opmode, Kay key);
public void init(int opmode, Certificate certificate);
public void init(int opmode, Kay key,
SecureRandom random);
public void init(int opmode,Certificate certificate,
SecureRandom random);
public void init(int opmode, Kay key,
AlgorithmParameterSpec params);
50
public void init(int opmode, Kay key,
AlgorithmParameterSpec params, SecureRandom random);
public void init(int opmode, Key key,
AlgorithmParameters params);
public void init(int opmode, Key key,
AlgorithmParameters params, SecureRandom random);
If a Cipher object that requires parameters, such as an IV, is
initialized for encryption and no parameters are supplied, the
underline cipher implementation is supposed to supply the required
parameters. However, if it is for decryption and no parameters are
supplied to the init method, an InvalidKeyException or
InvalidAlgorithmParameterException will raised.
51
To encrypt or decrypt a message which is not too large, you can
use a single step.
public byte[] doFinal(byte[] input);
public byte[] doFinal(byte[] input, int inputOffset,
int inputLen);
public int doFinal(byte[] input, int inputOffset, int inputLen,
byte[] output);
public int doFinal(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset);
52
When the size of the message is unknown or the message is large,
you can use multiple steps. First supply the data using update.
public byte[] update(byte[] input);
public byte[] update(byte[] input, int inputOffset, int inputLen);
public int update(byte[] input, int inputOffset, int inputLen,
byte[] output);
public int update(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset);
Then terminate the operation using doFinal as mentioned before
or the following (if no data left).
public byte[] doFinal();
public int doFinal(byte[] output, int outputOffset);
53
To wrap a Key, first initialize the Cipher object for WRAP MODE, and
then call the following:
public final byte[] wrap(Key key);
To unwrap the key data, need the information: The name of the
key algorithm(may use public String getAlgorithm();) , the
type of the wrapped key (Cipher.SECRET KEY,
Cipher.PRIVATE KEY, or Cipher.PUBLIC KEY).
Then use an initialized Cipher object for UNWRAP MODE and call
public final Key unwrap(byte[] wrappedKey, String
wrappedKeyAlgorithm, int wrappedKeyType);
54
The parameters used by the Cipher implementation can be
retrieved by getParameters method, which returns the parameters
as a java.security.Algorithms object of NULL. If the parameter is an
initialization vector, then it can be retrieved by getIV.
public AlgorithmParameters getParameters()
public byte[] getIV()
Example
// get cipher object for password-based encryption
Cipher c = Cipher.getInstance("PBEWithMD5AndDES);
c.init(Cipher.ENCRYPT_MODE, myKey);
byte[] cipherText = c.doFinal("an example".getByte());
AlgorithmParameters algParams = c.getParameters();
byte[] encodedAlgParams = algParams.getEncoded();
55
PBEWithMD5AndDES uses a set of parameters, comprising a salt and
iteration count. The javax.crypto.spec.PBEParameterSpec class
can be used to initialize a Cipher object implementing
PBEWithMD5AndDES with a given salt and iteration count.
The same parameters that were used for encryption must be used
for decryption:
AlgorithmParameters algParams;
algParams = AlgorithmParameters.getInstance("PBEWithMD5AndDES");
algParams.init(encodeAlgParams);
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
c.init(Cipher.DECRPT_MODE, myKey, algParams);
56
Some of the update and doFinal methods of Cipher allow the
caller to specify the output buffer into which to encrypt or decrypt
the data. In these cases, it is important to pass a buffer that is
large enough to hold the result.
The following method in Cipher can be used to determine how big
the output buffer should be:
public int getOutputSize(int inputLen)
57
The engine class javax.crypto.KeyGenerator is used to generate
secret key for symmetric encryptions.
To create an object:
public static KeyGenerator getInstance(String algorithm);
public static KeyGenerator getInstance(String algorithm,
String provider);
public static KeyGenerator getInstance(String algorithm,
Provider provider);
58
To initialize the object as algorithm-independent manner:
public void init(SecureRandom random);
public void init(int keysize);
public void init(int keysize, SecureRandom random);
To initialize the object associate with algorithm-specific
parameters:
public void init(AlgorithmParameterSpec params);
public void init(AlgorithmParameterSpec params,
SecureRandom random);
To generate a secret key:
public SecretKey generateKey();
59
javax.crypto.KeyAgreement class provides the functionality of a
key agreement protocol.
Each party involved in the key agreement has to create a
KeyAgrement object.
public static KeyAgreement getInstance(String algorithm);
public static KeyAgreement getInstance(String algorithm
String provider);
public static KeyAgreement getInstance(String algorithm
Provider provider);
60
To initialeze the KeyAgreement object:
public void init(Key key);
public void init(Key key, SecureRandom random);
public void init(Key key, AlgorithmParameterSpec params);
public void init(Key key, AlgorithmParameterSpec params,
SecureRandom random);
In the case of Diffie-Hellman, you initialize it with your private key.
Additional initialization information may required. If the required
key-agreement algorithm requires the specification of algorithm
parameters and if only a key but no parameters are provided to
initialize the KeyAgreement object, the key must contain the
required algorithm parameters.
61
Every key-agreement protocol consists of a number of phases that
need to be executed by each party involved in the key agreement.
To execute the next phase in the key agreement:
public Key doPhase(Key key, boolean lastPhase);
The key contains the key to be processed by that phase, which can
be a public key of the other party or an intermediate key that was
generated by a previous phase.
The lastPhase specifies if the phase to be executed is the last one.
Then each party can compute the shared secret:
public byte[] generateSecret();
public int generateSecret(byte[] sharedSecret, int offset);
public SecretKey generateSecret(String algorithm);
62
javax.crypto.Mac provides the functionality of a message
authentication code. Create instance:
public static Mac getInstance(String algorithm);
public static Mac getInstance(String algorithm,
String provider);
public static Mac getInstance(String algorithm,
Provider provider);
Initialization:
public void init(Key key);
public void init(Key key, AlgorithmParameterSpec params);
63
You can initialize the Mac object with any secret-key object that
implements the javax.crypto.SecretKey interface, which could
be an object returned by
javax.crypto.KeyGenerator.generateKey() or result returned
by javax.crypto.KeyAgreement.generateSecret() or
javax.crypto.spec.SecretKeySpec.
Finally to compute a Mac:
public byte[] doFinal(byte[] input);
To compute the MAC of some data in multiple steps, you can first
make one of more calls of the update methods to supply all the
data.
64