FileDocCategorySizeDatePackage
RSASig.javaAPI DocphoneME MR2 API (J2ME)8368Wed May 02 18:00:00 BST 2007com.sun.midp.crypto

RSASig

public final class RSASig extends Object
Implements RSA Signatures.

Fields Summary
String
alg
Current algorithm.
MessageDigest
md
Current message digest.
Cipher
c
Current cipher.
RSAKey
k
Current key.
byte[]
prefix
Signature prefix.
Constructors Summary
RSASig(byte[] sigPrefix, MessageDigest messageDigest)
Constructs an RSA signature object that uses the specified signature algorithm.

param
sigPrefix Prefix for the signature
param
messageDigest Message digest for the signature
exception
NoSuchAlgorithmException if RSA is not available in the caller's environment.

    

                                              
       
              
        prefix = sigPrefix;
        md = messageDigest;

        try {
            c = Cipher.getInstance("RSA");
        } catch (NoSuchPaddingException e) {
            // we used the default mode and padding this should not happen
            throw new NoSuchAlgorithmException();
        }
    
Methods Summary
public intgetLength()
Gets the byte-length of the signature.

return
the byte-length of the signature produced by this object

        if (k == null)
            return (short)0;
        else  // return the modulus length in bytes
            return (short)k.getModulusLen();
    
public voidinitSign(PrivateKey theKey)
Initializes the RSASig object with the appropriate Key for signature creation.

param
theKey the key object to use for signing
exception
InvalidKeyException if the key type is inconsistent with the mode or signature implementation.

        if (!(theKey instanceof RSAPrivateKey)) {
            throw new InvalidKeyException();
        }

        c.init(Cipher.ENCRYPT_MODE, theKey);

        k = (RSAKey)theKey;
    
public voidinitVerify(PublicKey theKey)
Initializes the RSASig object with the appropriate Key for signature verification.

param
theKey the key object to use for verification
exception
InvalidKeyException if the key type is inconsistent with the mode or signature implementation.

        if (!(theKey instanceof RSAPublicKey)) {
            throw new InvalidKeyException();
        }

        c.init(Cipher.DECRYPT_MODE, theKey);

        k = (RSAKey)theKey;
    
public intsign(byte[] sigBuf, int sigOff, int sigLen)
Generates the signature of all/last input data. A call to this method also resets this signature object to the state it was in when previously initialized via a call to init(). That is, the object is reset and available to sign another message.

param
sigBuf the output buffer to store signature data
param
sigOff starting offset within the output buffer at which to begin signature data
param
sigLen max byte length of signature data
return
number of bytes of signature output in sigBuf
exception
SignatureException if this signature object is not initialized properly, or len is less than the actual signature

        if (k == null || !(k instanceof RSAPrivateKey)) {
            throw new SignatureException("Illegal State");
        }

        if (sigLen < k.getModulusLen()) {
            throw new SignatureException("Buffer too short");
        }

        byte[] data = new byte[prefix.length + md.getDigestLength()];

        // Include the OID of signing algorithm in padding
        System.arraycopy(prefix, 0, data, 0, prefix.length);
        try {
            md.digest(data, prefix.length, md.getDigestLength());

            /*
             * we can cast to a short because a private key encryption is
             * is less than the key length, which is a short.
             */
            return c.doFinal(data, 0, data.length, sigBuf, sigOff);
        } catch (GeneralSecurityException ce) {
            throw new SignatureException(ce.getMessage());
        }
    
public voidupdate(byte[] inBuf, int inOff, int inLen)
Accumulates a signature of the input data. When this method is used, temporary storage of intermediate results is required. This method should only be used if all the input data required for the signature is not available in one byte array. The sign() or verify() method is recommended whenever possible.

param
inBuf the input buffer of data to be signed
param
inOff starting offset within the input buffer for data to be signed
param
inLen the byte length of data to be signed
exception
SignatureException if this signature object is not initialized properly.

        if (k == null) {
            throw new SignatureException("Illegal State");
        }

        md.update(inBuf, inOff, inLen);
    
public booleanverify(byte[] sigBuf, int sigOff, int sigLen)
Verifies the signature of all/last input data against the passed in signature. A call to this method also resets this signature object to the state it was in when previously initialized via a call to init(). That is, the object is reset and available to verify another message.

param
sigBuf the input buffer containing signature data
param
sigOff starting offset within the sigBuf where signature data begins
param
sigLen byte length of signature data
return
true if signature verifies, false otherwise
exception
SignatureException if this signature object is not initialized properly, or the passed-in signature is improperly encoded or of the wrong type, etc.

        if (k == null || !(k instanceof RSAPublicKey)) {
            throw new SignatureException("Illegal State");
        }

        byte[] res = null;
        int val;
        byte[] digest = new byte[md.getDigestLength()];

        try {
            md.digest(digest, 0, digest.length);
            res = new byte[k.getModulusLen()];
            val = c.doFinal(sigBuf, sigOff, sigLen, res, 0);
        } catch (IllegalArgumentException iae) {
            throw new SignatureException(iae.getMessage());
        } catch (GeneralSecurityException e) {
            return false;
        }

        int size = prefix.length + md.getDigestLength();

        if (val != size) {
            return false;
        }

        // Match the prefix corresponding to the signature algorithm
        for (int i = 0; i < prefix.length; i++) {
            if (res[i] != prefix[i]) {
                return false;
            }
        }

        for (int i = prefix.length; i < size; i++) {
            if (res[i] != digest[i - prefix.length]) {
                    return false;
            }
        }

        return true;