Skip Headers

Oracle® Security Developer Tools Reference 10g Release 3 (10.1.3) B25372-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 2 Oracle Crypto

This chapter provides information about using the Oracle Crypto Software Development Kit (SDK). Oracle Crypto allows Java developers to develop applications that ensure data security and integrity.

This chapter contains the following topics:

- Oracle Crypto Features and Benefits

- Setting Up Your Oracle Crypto Environment

- Core Classes and Interfaces

- The Oracle Crypto Java API Reference

## 2.1 Oracle Crypto Features and Benefits

Oracle Crypto provides the following features:

- Public key cryptography algorithms such as RSA

- Digital signature algorithms such as DSA, RSA, and Elliptic Curve Cryptography (ECC)

- Key exchange algorithms such as Diffie-Hellman and Elliptic Curve Cryptography (ECC)

- Symmetric cryptography algorithms such as Blowfish, AES, DES, 3DES, RC2, and RC4

- Message digest algorithms such as MD2, MD4, MD5, SHA-1, SHA-256, SHA-384, and SHA-512

- MAC algorithms such as HMAC-MD5 and HMAC-SHA-1

- Methods for building and parsing ASN.1 objects

### 2.1.1 Oracle Crypto Packages

Oracle Crypto contains the following packages:

- `oracle.security.crypto.core` - Basic cryptographic primitives

- `oracle.security.crypto.core.math` - Utility classes for handling mathematical functions

- `oracle.security.crypto.util` - Various utility classes

- `oracle.security.crypto.asn1` - Facilities for reading and writing both BER-encoded and DER-encoded ASN.1 structures

## 2.2 Setting Up Your Oracle Crypto Environment

This section explains how to set up your environment to use Oracle Crypto. It contains the following topics:

- System Requirements for Oracle Crypto

- Setting the CLASSPATH Environment Variable

### 2.2.1 System Requirements for Oracle Crypto

In order to use the Oracle Crypto SDK, your system must have the Java Development Kit (JDK) version 1.2.2 or higher.

### 2.2.2 Setting the CLASSPATH Environment Variable

Your `CLASSPATH` environment variable must contain the full path and file names to the required jar and class files. Make sure that the `osdt_core.jar` file is included in your `CLASSPATH`.

#### 2.2.2.1 Setting the CLASSPATH on Windows

To set your `CLASSPATH` on Windows:

1. In your Windows Control Panel, select System.

2. In the System Properties dialog, select the Advanced tab.

3. Click Environment Variables.

4. In the User Variables section, click New to add a `CLASSPATH` environment variable for your user profile. If a `CLASSPATH` environment variable already exists, select it and click Edit.

5. Add the full path and file names for all of the required jar and class files to the `CLASSPATH`.

   For example, your `CLASSPATH` might look like this:

       C:\ORACLE_HOME\jlib\osdt_core.jar

6. Click OK.

#### 2.2.2.2 Setting the CLASSPATH on UNIX

On UNIX, set your `CLASSPATH` environment variable to include the full path and file name of all of the required jar and class files. For example:

    setenv CLASSPATH $CLASSPATH:$ORACLE_HOME/jlib/osdt_core.jar

## 2.3 Core Classes and Interfaces

This section provides information and code samples for using the core classes and interfaces of Oracle Crypto. The core classes and interfaces are divided into the following categories:

- Keys

- Key Generation

- Ciphers

- Signatures

- Message Digests

- Key Agreement

- Pseudo-Random Number Generators

### 2.3.1 Keys

Oracle Crypto provides the following classes and interfaces for working with keys:

- The oracle.security.crypto.core.Key Interface

- The oracle.security.crypto.core.PrivateKey Interface

- The oracle.security.crypto.core.PublicKey Interface

- The oracle.security.crypto.core.SymmetricKey Class

#### 2.3.1.1 The oracle.security.crypto.core.Key Interface

This interface represents a key which may be used for encryption or decryption, for generating or verifying a digital signature, or for generating or verifying a MAC. A key may be a private key, a public key, or a symmetric key.

#### 2.3.1.2 The oracle.security.crypto.core.PrivateKey Interface

This interface represents a private key which may be an `RSAPrivateKey`, a `DSAPrivateKey`, a `DHPrivateKey`, an `ECPrivateKey` or a `PrivateKeyPKCS8` instance that holds an encrypted private key.

#### 2.3.1.3 The oracle.security.crypto.core.PublicKey Interface

This interface represents a public key which may be a `RSAPublicKey`, a `DSAPublicKey`, a `DHPublicKey` or a `ECPublicKey` instance.

#### 2.3.1.4 The oracle.security.crypto.core.SymmetricKey Class

This class represents a symmetric key which may be used for encryption, decryption or for MAC operations.

### 2.3.2 Key Generation

Oracle Crypto provides the following classes for key generation:

- The oracle.security.crypto.core.KeyPairGenerator Class

- The oracle.security.crypto.core.SymmetricKeyGenerator Class

#### 2.3.2.1 The oracle.security.crypto.core.KeyPairGenerator Class

This abstract class is used to generate key pairs such as RSA, DSA, Diffie-Hellman or ECDSA key pairs.

To get a new key pair generator, create a new instance of `KeyPairGenerator` by calling the static `getInstance()` method with an `AlgorithmIdentifier` object as a parameter. Example 2-1 shows how to create a new `KeyPairGenerator` instance:

Example 2-1 Code Example for Creating a New `KeyPairGenerator` Instance

    KeyPairGenerator kpg = KeyPairGenerator.getInstance(AlgID.rsaEncryption);

This creates a `KeyPairGenerator` object from one of the concrete classes: `RSAKeyPairGenerator`, `DSAKeyPairGenerator`, `DHKeyPairGenerator`, or `ECKeyPairGenerator`.

Initialize the key pair generator by using one of the `initialize()` methods. Generate the key pair with the `generateKeyPair()` method. Example 2-2 shows how to initialize the key pair generator and then generate a key pair:

Example 2-2 Code Example for Initializing and Generating a Key Pair

    kpg.initialize(1024, RandomBitsSource.getDefault());
    KeyPair kp = kpg.generateKeyPair();
    PrivateKey privKey = kp.getPrivate();
    PublicKey pubKey = kp.getPublic();

Save the keys using the `output()` method, or in the case of the private key, encrypt it and save it using the `PrivateKeyPKCS8` class. Example 2-3 shows how to save a key pair.

Example 2-3 Code Example for Saving a Key Pair

    FileOutputStream pubKeyFos = new
    FileOutputStream("my-pub-key.der");
    pubKey.output(pubKeyFos);
    pubKeyFos.close();

    PrivateKeyPKCS8 privKeyPKCS8 =
        new PrivateKeyPKCS8(privKey, "myPassword");
    FileOutputStream privKeyFos =
        new FileOutputStream("my-encrypted-priv-key.der");
    privKeyPKCS8.output(privKeyFos);
    privKeyFos.close();

#### 2.3.2.2 The oracle.security.crypto.core.SymmetricKeyGenerator Class

This class generates symmetric key pairs such as Blowfish, DES, 3DES, RC4, RC2, AES, and HMAC keys.

To get a new symmetric key generator, create a new instance of `SymmetricKeyGenerator` by calling the static `getInstance()` method with an `AlgorithmIdentifier` object as a parameter. Example 2-4 shows how to create a new `SymmetricKeyGenerator` instance:

Example 2-4 Code Example for Creating a New `SymmetricKeyGenerator` Instance

    SymmetricKeyGenerator skg = SymmetricKeyGenerator.getInstance(AlgID.desCBC);

Generate the key pair with the `generateKey()` method. You can then save the key by using the `getEncoded()` method. Example 2-5 shows how to generate and save a symmetric key pair.

Example 2-5 Code Example for Generating and Saving Symmetric Keys

    SymmetricKey sk = skg.generateKey();

    FileOutputStream symKeyFos =
        new FileOutputStream("my-sym-key.der");
    symKeyFos.write(sk.getEncoded());
    symKeyFos.close();

### 2.3.3 Ciphers

The Oracle Crypto Cipher classes and interfaces are divided into the following categories:

- Symmetric Ciphers

- The RSA Cipher

- Password Based Encryption

#### 2.3.3.1 Symmetric Ciphers

The symmetric ciphers are made up of two categories: the block ciphers (such as Blowfish, DES, 3DES, RC2, and AES) and the stream ciphers (such as RC4).

A symmetric cipher can be used for four types of operations:

- Encryption of raw data. Use one of the `encrypt()` methods by passing data to be encrypted.

- Decryption of encrypted data. Use one of the `decrypt()` methods by passing encrypted data to be decrypted.

- Wrapping of private or symmetric keys. Use one of the `wrapKey()` methods by passing the private or symmetric key to be encrypted.

- Unwrapping of private or symmetric encrypted keys. Use either the `unwrapPrivateKey()` or the `unwrapSymmetricKey()` method by passing the encrypted private or symmetric key to be decrypted.

The concrete block cipher classes extend the abstract `oracle.security.crypto.core.BlockCipher` class, which extends the `oracle.security.crypto.core.Cipher` class. The stream cipher classes directly extend the `oracle.security.crypto.core.Cipher` class.

To create a new instance of `Cipher`, call the static `getInstance()` method with an `AlgorithmIdentifier` and a `Key` object as parameters.

Example 2-6 shows how to create a new Cipher instance. First an RC4 object is created and initialized with the specified key. Second a block cipher DES object is created and initialized with the specified key and padding. This creates a cipher and initializes it with the passed parameters. To re-initialize an existing cipher, call one of the `initialize()` methods.

Example 2-6 Code Example for Creating a `Cipher` Instance

    Cipher rc4 = Cipher.getInstance(AlgID.rc4, rc4SymKey);

    Cipher desCipher = Cipher.getInstance(AlgID.desCBC, desSymKey, Padding.PKCS5);

When using CBC ciphers, the `AlgorithmIdentifier` object may hold cryptographic parameters such as the initialization vector (IV) or the effective key length for RC2 ciphers. To specify these parameters when creating or initializing block ciphers, build a `CBCAlgorithmIdentifier` object or `RC2AlgorithmIdentifier` object with the cryptographic parameters. Example 2-7 shows how to create and initialize a CBC cipher and a RC2 cipher.

Example 2-7 Code Example for Creating and Initializing CBC Ciphers

    CBCAlgorithmIdentifier cbcAlgID =
        new CBCAlgorithmIdentifier(AlgID.desCBC, iv);
    desCipher.initialize(cbcAlgID, desSymKey, Padding.PKCS5);
    RC2AlgorithmIdentifier rc2AlgID =
        new RC2AlgorithmIdentifier(iv, 56);
    BlockCipher rc2Cipher =
        (BlockCipher)Cipher.getInstance(rc2AlgID, rc2SymKey, Padding.PKCS5);

#### 2.3.3.2 The RSA Cipher

The RSA cipher is an implementation of PKCS#1 v2.0 that supports the RSAES-OAEP and RSAES-PKCS1-v1_5 encryption schemes. According to the specification, RSAES-OAEP is recommended for new applications, and RSAES-PKCS1-v1_5 is included only for compatibility with existing applications and protocols.

The encryption schemes are used to combine RSA encryption and decryption primitives with an encoding method. Encryption and decryption can only be done through the methods `encrypt(byte[])` and `decrypt(byte[])`.

You can use an RSA cipher for four types of operations:

- Encryption of raw data. Use one of the `encrypt()` methods by passing data to be encrypted.

- Decryption of encrypted data. Use one of the `decrypt()` methods by passing encrypted data to be decrypted.

- Wrapping of keys. Use the `wrapKey()` method by passing the key to be encrypted.

- Unwrapping of encrypted keys. Use the `unwrapSymmetricKey()` method by passing the encrypted key to be decrypted.

To create a new instance of `Cipher`, call the static `getInstance()` method with `AlgorithmIdentifier` and `Key` objects as parameters. Example 2-8 demonstrates how to create an `RSApkcs1` object and initialize it with the specified key. The cipher can then be used to encrypt or decrypt data.

Example 2-8 Code Example for Creating and Initializing an RSA Cipher

    Cipher rsaEnc = Cipher.getInstance(AlgID.rsaEncryption, pubKey);
    byte[] encryptedData = rsaEnc.encrypt(data);
    Cipher rsaDec = Cipher.getInstance(AlgID..rsaEncryption, privKey);
    byte[] decryptedData = rsaDec.decrypt(encryptedData);

When using RSA ciphers, the `AlgorithmIdentifier` object may hold cryptographic parameters such as the mask generation function for RSAES-OAEP. To specify these parameters when creating or initializing RSA ciphers, build an `OAEPAlgorithmIdentifier`, or use the default one located in the `oracle.security.crypto.core.AlgID` interface.

#### 2.3.3.3 Password Based Encryption

The abstract `oracle.security.crypto.core.PBE` class provides methods for Password Based Encryption (PBE) operations. The concrete classes extending the PBE are the `PKCS5PBE` and `PKCS12PBE` classes.

You can use a PBE object for four types of operations:

- Encryption of raw data. For example:

      byte[] encData = pbeEnc.encrypt("myPassword", data);

- Decryption of encrypted data. For example:

      byte[] decData = pbeDec.decrypt("myPassword", encData);

- Wrapping of private or symmetric keys. For example:

      byte[] encPrivKey = pbeEnc.encryptPrivateKey("myPassword", privKey);
      byte[] encSymKey = pbeEnc.encryptSymmetricKey("myPassword", symKey);

- Unwrapping of private or symmetric encrypted keys. For example:

      PrivateKey decPrivKey = pbeDec.decryptPrivateKey("myPassword", encPrivKey);
      SymmetricKey decSymKey = pbeDec.decryptSymmetricKey("myPassword", encSymKey);

To create a new instance of PBE, call the static `getInstance()` method with a `PBEAlgorithmIdentifier` object as a parameter. For example:

    PBE pbeEnc = PBE.getInstance(pbeAlgID);

This will create a `PKCS5PBE` object and initialize it with the specified PBE algorithm. The PBE can then be used to encrypt or decrypt data, wrap or unwrap keys.

When using PBE objects, the `AlgorithmIdentifier` object may hold cryptographic parameters such as the salt or the iteration count as well as the ASN.1 Object Identifier specifying the PBE algorithm to use. To specify these parameters when creating or initializing PBEs, build a `PBEAlgorithmIdentifier` object with the cryptographic parameters.

Example 2-9 Code Example for Creating a PBE Object

    PBEAlgorithmIdentifier pbeAlgID =
        new PBEAlgorithmIdentifier(PBEAlgorithmIdentifier.pbeWithMD5AndDES_CBC, salt, 1024);
    pbeEnc.initialize(pbeAlgID);
    PBE pbeDec = PBE.getInstance(pbeAlgID);

### 2.3.4 Signatures

The `oracle.security.crypto.core.Signature` abstract class provides methods to sign and verify signatures. The concrete classes extending the `Signature` class are the `RSAMDSignature`, `DSA` and the `ECDSA` classes.

The algorithms available for signature operations are:

- For RSA: `AlgID.md2WithRSAEncryption`, `AlgID.md5WithRSAEncryption` and `AlgID.sha_1WithRSAEncryption`

- For DSA: `AlgID.dsaWithSHA1`

- For ECDSA: `AlgID.ecdsaWithSHA1`

To create a new instance of `Signature`, call the static `getInstance()` method with an `AlgorithmIdentifier` and a `PrivateKey` or `PublicKey` objects as parameters. Example 2-10 shows how to create a new `Signature` object and initialize it with the specified algorithm.

Example 2-10 Code Example for Creating a New `Signature` Object

    Signature rsaSign = Signature.getInstance(AlgID.md5WithRSAEncryption);
    Signature rsaVerif = Signature.getInstance(AlgID.md5WithRSAEncryption);

Example 2-11 shows how to set the keys for the `Signature` objects and set the document to be signed or verified.

Example 2-11 Code Example for Setting Signature Keys and Documents

    rsaSign.setPrivateKey(privKey);
    rsaSign.setDocument(data);
    rsaVerif.setPublicKey(pubKey);
    rsaVerif.setDocument(data);

Example 2-12 shows how to compute the signature using the private key or to verify the signature using the public key and the signature bytes.

Example 2-12 Code Example for Computing or Verifying a Signature

    byte[] sigBytes = rsaSign.sign();
    boolean verified = rsaVerif.verify(sigBytes);

### 2.3.5 Message Digests

Oracle Crypto provides the following message digest classes:

- The oracle.security.crypto.core.MessageDigest Class

- The oracle.security.crypto.core.MAC Class

#### 2.3.5.1 The oracle.security.crypto.core.MessageDigest Class

The `MessageDigest` abstract class provides methods to hash and digest data. The concrete classes extending the `MessageDigest` class are the `MD2`, `MD4`, `MD5` and the `SHA` classes.

The available algorithms for message digest operations are: `AlgID.md2`, `AlgID.md4`, `AlgID.md5`, `AlgID.sha_1`, `AlgID.sha_256`, `AlgID.sha_384` and `AlgID.sha_512`.

The basic process for creating a message digest is as follows:

1. Create a new instance of `MessageDigest` by calling the static `getInstance()` method with an `AlgorithmIdentifier` object as a parameter.

2. Add the data to be digested.

3. Compute the hash value.

Example 2-13 shows how to create an MD5 message digest object.

Example 2-13 Code Example for Creating a Message Digest

    //Create a new MD5 MessageDigest object
    MessageDigest md5 = Signature.getInstance(AlgID.md5);

    //Add the data to be digested
    md5.udpate(data1);
    md5.udpate(data2);

    //Compute the hash value
    md5.computeCurrent();
    byte[] digestBits = md5.getDigestBits();

#### 2.3.5.2 The oracle.security.crypto.core.MAC Class

The `MAC` abstract class provides methods to compute and verify a Message Authentication Code (MAC). The concrete class extending the `MAC` is the `HMAC` class.

The available algorithms for MAC operations are: `AlgID.hmacMD5` and `AlgID.hmacSHA`.

The basic process for creating a MAC is as follows:

1. Create a new instance of `MAC` by calling the static `getInstance()` method with an `AlgorithmIdentifier` and a `SymmetricKey` object as a parameter.

2. Add the data to be digested.

3. Compute the MAC value and verify it.

Example Example 2-14 shows how to create a new HMAC object with the HMAC-SHA1 algorithm.

Example 2-14 Code Example for Creating a MAC

    //Create an HMAC object with the HMAC-SHA1 algorithm
    MAC hmacSha1Compute = MAC.getInstance(AlgID.hmacSHA, hmacSha1Key);

    //Add the data to be digested
    hmacSha1Compute.udpate(data);

    //Compute the MAC value and verify
    byte[] macValue = hmacSha1Compute.computeMAC();
    boolean verified = hmacSha1Verify.verifyMAC(data, macValue);

### 2.3.6 Key Agreement

The `oracle.security.crypto.core.KeyAgreement` class abstract class provides methods for public key agreement schemes such as Diffie-Hellman. The concrete classes extending the `KeyAgreement` class are the `DHKeyAgreement` and the `ECDHKeyAgreement` classes.

The available algorithms for key agreement operations are: `AlgID.dhKeyAgreement` and `ECDHKeyAgreement` (Elliptic Curve Diffie-Hellman key agreement).

The basic process for key agreement is as follows:

1. Create a new instance of `KeyAgreement` by calling the static `getInstance()` method with an `AlgorithmIdentifier` object as a parameter.

2. Set the local private key and the other party's public key.

3. Compute the shared secret value.

Example 2-15 shows how to perform key agreement.

Example 2-15 Code Example for Key Agreement

    //Create a DH key agreement object
    KeyAgreement dh = KeyAgreement.getInstance(AlgID.dhKeyAgreement);

    //Set the private key and public key
    dh.setPrivateKey(privKey);
    dh.setPublicKey(otherPubKey);

    //Compute the shared secret
    byte[] sharedSecret = dh.generateSecret();

### 2.3.7 Pseudo-Random Number Generators

In cryptography, random numbers are used to generate keys. Cryptographic systems need cryptographically strong (pseudo) random numbers that cannot be guessed by an attacker.

Oracle Crypto provides the following pseudo-random number generator (PRNG) classes:

- The oracle.security.crypto.core.RandomBitsSource class

- The oracle.security.crypto.core.EntropySource class

#### 2.3.7.1 The oracle.security.crypto.core.RandomBitsSource class

`RandomBitsSource` is an abstract class representing secure PRNG implementations. Note that, by the very nature of PRNGs, the security of their output depends on the amount and quality of seeding entropy used. Implementing classes should provide guidance as to their proper initialization and use. The concrete classes extending the `RandomBitsSource` are the `MD5RandomBitsSource`, `SHA1RandomBitsSource`, and the `DSARandomBitsSource` classes.

Create a new instance of `RandomBitsSource` by calling the static `getDefault()` method to return the default PRNG:

    RandomBitsSource rbs = RandomBitsSource.getDefault();

A `RandomBitsSource` object can also be created by instantiating one of the subclasses:

    RandomBitsSource rbs = new SHA1RandomBitsSource();

By default, a newly created PRNG created from a subclass will be seeded. To seed a generic `RandomBitsSource` object, use one of the seed methods by using a byte array or an `EntropySource` object:

    rbs.seed(myByteArray);

The object is then ready to generate random data:

    rbs.randomBytes(myRandomByteArray);

#### 2.3.7.2 The oracle.security.crypto.core.EntropySource class

The `EntropySource` class provides a source of seed material for the PRNGs. The concrete classes extending the `EntropySource` are the `SpinnerEntropySource` and `SREntropySource` classes.

Create a new instance of `EntropySource` by calling the static `getDefault()` method to return the default entropy source:

    EntropySource es = EntropySource.getDefault();

You can also create an `EntropySource` object by instantiating one of the subclasses:

    EntropySource rbs = new SpinnerEntropySource();

The entropy source is readied for use by using one of the `generateByte` methods:

    es.generateBytes(mySeedingArray);

## 2.4 The Oracle Crypto Java API Reference

The Oracle Crypto Java API reference (Javadoc) is available at:

Oracle Security Developer Tools Crypto Java API Reference