AES-256 encryption and WebMethods 6.5

Hi guys,
i’m running on WM 6.5 platform and i created a java service which encrypts and decrypts strings using AES-256 algorithm.

For this i wrote a JAR library which uses the AES-256 and i call it from the java web methods service.

I compiled and built my library with jdk1.5.0_15 and also had in the JRE the unlimited strength policy files for this jdk version.

Now when i run in any IDE a test for my library the encryption/decryption work fine, but when i call my classes from the WM java service i get this:

IllegalBlockSizeException:javax.crypto.IllegalBlockSizeException: The total length of the input data processed must be a multiple of the cipher mode block size (16 bytes); final input block was only a partial block containing 4 bytes

Normally if i don’t add the unlimited policy files to the JRE i would get an InvalidKeySizeException, but i got the one above from the first try in WM.

I need help to make my library work.

Thx, Marius.

If you remove the unlimited strength policy files from your IDE, do you get same error?

If so try adding it to IS JDK.

I can’t remember but there is a JVM argument similar to -Djava.security=all or something like that which will write all security debug information to STDOUT and you can get some hints.

It may be a character encoding issue if you’re trying to manipulate strings. Are you specifying a size of some sort when calling the encryption methods?

thought about it but no. im not specifying anything.

The thing that ennoys me is thatwhen i call my encryption functions from a normal java class they work without any proble.

When i encrypt i encode in base 64 and when i decrypt i decode in base 64.

Do you know if your IS is configured to use a character encoding other than UTF-8 as the default?

Doing base-64 encoding/decoding probably isn’t a factor. Based on the exception, it is failing during encryption, not during conversion to/from base-64.

This is the java code i compiled with jdk1.5.0_15 with the unlimited strength policy files

package com.ibx.kraft.sso.crypto;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.jboss.seam.util.Base64;

/**

  • Class used to decrypt and encrypt strings using a AES-256
  • @author mperciun

*/
public abstract class CryptoAES {

/**
 * Method that returns an array of binar bytes from an array of hexadecimal
 * bytes Used for encryption/decryption
 * 
 * @param hexValue
 * @return
 */
private static byte[] getBinaryDataFromHex(byte[] hexValue) {
    int block = 0;
    String HEX_STRING = "0123456789ABCDEF";
    byte[] data = new byte[hexValue.length / 2];
    int index = 0;
    boolean next = false;

    for (int i = 0; i < hexValue.length; i++) {
        block <<= 4;
        int pos = HEX_STRING.indexOf(Character
                .toUpperCase((char) hexValue[i]));
        if (pos > -1)
            block += pos;

        if (next) {
            data[index] = (byte) (block & 0xff);
            index++;
            next = false;
        } else
            next = true;
    }

    return data;
}

/**
 * Generate the SecretKey object from the encryption key
 * 
 * @param value
 * @return
 */
private static SecretKeySpec generateKey(String value) {

    // generate the key object which we pass to the cipher
    SecretKeySpec keySpec = new SecretKeySpec(getBinaryDataFromHex(value
            .getBytes()), "AES");
    return keySpec;

}

/**
 * Encrypts a string
 * 
 * @param clearString
 * @param publicKey
 * @return
 * @throws InvalidKeyException
 * @throws IllegalBlockSizeException
 * @throws NoSuchAlgorithmException
 * @throws NoSuchPaddingException
 * @throws BadPaddingException
 */
public static String encryptString(String clearString, String publicKey)
        throws InvalidKeyException, IllegalBlockSizeException,
        NoSuchAlgorithmException, NoSuchPaddingException,
        BadPaddingException {

    Cipher encryptCipher = Cipher.getInstance("AES");

    SecretKeySpec key = generateKey(publicKey);
    encryptCipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] cipherText = encryptCipher.doFinal(clearString.getBytes());

    return Base64.encodeBytes(cipherText).toString();

}

/**
 * Decrypts a string
 * 
 * @param clearString
 * @param publicKey
 * @return
 * @throws InvalidKeyException
 * @throws IllegalBlockSizeException
 * @throws NoSuchAlgorithmException
 * @throws NoSuchPaddingException
 * @throws BadPaddingException
 */
public static String decryptString(String encryptedString, String publicKey)
        throws InvalidKeyException, IllegalBlockSizeException,
        NoSuchAlgorithmException, NoSuchPaddingException,
        BadPaddingException {

    Cipher decryptCipher = Cipher.getInstance("AES");

    byte[] toBeDecrypted = Base64.decode(encryptedString);

    SecretKeySpec key = generateKey(publicKey);
    decryptCipher.init(Cipher.DECRYPT_MODE, key);

    byte[] decipherText = decryptCipher.doFinal(toBeDecrypted);

    return new String(decipherText);

}

}

If i don’t install the unlimited policy files on my computer i get a InvalidKeyException but on the WM machine i get that IllegalBlockSizeException.

This is the WM Java Service:

// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String encryptionKey = IDataUtil.getString( pipelineCursor, “encryptionKey” );
pipelineCursor.destroy();

try{
//Generate password
String generatedPassword=GeneratePass.getCompliantPassword();

//Encrypt the new password
String encryptedPassword = CryptoAES.encryptString(“test”,“7E389A0F4B319BDD59A751F9DA9A9760CE0B2158D8F0C55252D4F7D1FF8773B6”);

// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor_1, “generatedEBPassword”, generatedPassword);
IDataUtil.put( pipelineCursor_1, “encryptedEBPassword”, encryptedPassword);

pipelineCursor_1.destroy();

} catch (InvalidKeyException ex) {
throw new ServiceException(“InvalidKeyException:” + ex.toString());
} catch (NoSuchPaddingException ex) {
throw new ServiceException(“NoSuchPaddingException:” + ex.toString());
} catch (IllegalBlockSizeException ex) {
throw new ServiceException(“IllegalBlockSizeException:” + ex.toString());
} catch (NoSuchAlgorithmException ex) {
throw new ServiceException(“NoSuchAlgorithmException:” + ex.toString());
} catch (BadPaddingException ex) {
throw new ServiceException(“BadPaddingException:” + ex.toString());
}

The data in there is for testing. The same encryption key works fine from a static java class.

So i narrowed down the problem. I moved the whole encryption code in a WM java service:

// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String encryptionKey = IDataUtil.getString( pipelineCursor, “encryptionKey” );
pipelineCursor.destroy();

try{

String test=“j9S2CysM”;
String key = “7E389A0F4B319BDD59A751F9DA9A9760CE0B2158D8F0C55252D4F7D1FF8773B6”;

byte bts = new byte[key.length() / 2];
for (int i = 0; i < bts.length; i++) {
bts[i] = (byte) Integer.parseInt(key.substring(2 * i,2 * i + 2), 16);
}

SecretKeySpec keySpec = new SecretKeySpec(bts, “AES”);

Cipher encryptCipher = Cipher.getInstance(“AES”);

encryptCipher.init(Cipher.ENCRYPT_MODE, keySpec);

byte cipherText = encryptCipher.doFinal(test.getBytes());

// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor_1, “encryptedEBPassword”, cipherText);

pipelineCursor_1.destroy();

} catch (InvalidKeyException ex) {
throw new ServiceException(“InvalidKeyException:” + ex.toString());
} catch (NoSuchPaddingException ex) {
throw new ServiceException(“NoSuchPaddingException:” + ex.toString());
} catch (IllegalBlockSizeException ex) {
throw new ServiceException(“IllegalBlockSizeException:” + ex.toString());
} catch (NoSuchAlgorithmException ex) {
throw new ServiceException(“NoSuchAlgorithmException:” + ex.toString());
} catch (BadPaddingException ex) {
throw new ServiceException(“BadPaddingException:” + ex.toString());
}

This should encrypt the text using AES (8 bytes text x 32 bytes key = 256 bytes).
The thing the error says is that the data to be processed is to small (8 bytes) for the key. If i make the string to be encrypted to be 16 chars it works.

Also if i change the algorithm to DES and change the key to 64 bits it works.

I’m not very good at encryption stuff but i think the problem is with the unlimited strenght jar files.