Question

I have the following CFML script in which I try to use the ColdFusion JAVA class found in coldfusion.sql.TwoFishCryptor:

<cfscript>
twofishcryptor = createObject("java","coldfusion.sql.TwoFishCryptor");
newPass = twofishcryptor.encrypt("p455w0rd");
</cfscript>

<cfoutput>Encrypted: #newPass#<br></cfoutput>

But I get the following error: enter image description here Below is the full JAVA class code:

package coldfusion.sql;

import java.io.PrintStream;

final class TwoFishCryptor
{
  private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  private static final byte[] HEX_BYTES = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
  private static final byte[] keyArray = { 86, -68, -54, 55, -108, -127, -90, 23, 9, 89, -6, -37, -52, -3, 64, 26 };
  Object key = null;
  int inputSize;

  TwoFishCryptor()
  {
    try
    {
      this.key = TwoFish_Algorithm.makeKey(keyArray);
    }
    catch (Exception e)
    {
      try
      {
        System.out.println(e.getMessage());
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
    this.inputSize = TwoFish_Algorithm.blockSize();
  }

  protected String encrypt(String cleartext)
  {
    byte[] input = cleartext.getBytes();
    byte[] paddedInput = new byte[this.inputSize];

    System.arraycopy(input, 0, paddedInput, 0, input.length > this.inputSize ? this.inputSize : input.length);
    if (input.length < this.inputSize) {
      for (int i = input.length; i < this.inputSize; i++) {
        paddedInput[i] = 0;
      }
    }
    byte[] encryptedBlock = TwoFish_Algorithm.blockEncrypt(paddedInput, 0, this.key);
    return toString(encryptedBlock, 0, encryptedBlock.length);
  }

  protected String decrypt(String encryptedText)
  {
    if ((encryptedText == null) || (encryptedText.length() == 0)) {
      return encryptedText;
    }
    byte[] input = toByte(encryptedText);
    if (input.length > this.inputSize)
    {
      System.out.println("corrupted data...");
      return "";
    }
    byte[] decryptBytes = TwoFish_Algorithm.blockDecrypt(input, 0, this.key);



    int paddingIndex = -1;
    for (int n = 0; n < decryptBytes.length; n++) {
      if (decryptBytes[n] == 0)
      {
        paddingIndex = n;
        break;
      }
    }
    byte[] paddingRemovedBytes;
    String paddingRemovedString;
    if (paddingIndex != -1)
    {
      paddingRemovedBytes = new byte[paddingIndex];
      System.arraycopy(decryptBytes, 0, paddingRemovedBytes, 0, paddingIndex);
      paddingRemovedString = new String(paddingRemovedBytes);
    }
    else
    {
      paddingRemovedBytes = new byte[decryptBytes.length];
      System.arraycopy(decryptBytes, 0, paddingRemovedBytes, 0, decryptBytes.length);
    }
    char[] decryptedChars = new char[paddingRemovedBytes.length];
    for (int m = 0; m < paddingRemovedBytes.length; m++) {
      decryptedChars[m] = ((char)paddingRemovedBytes[m]);
    }
    return new String(decryptedChars);
  }

  private boolean matches(String encryptedText, String clearText)
  {
    String newEncryptedText = encrypt(clearText);
    return encryptedText.equals(newEncryptedText);
  }

  private static boolean areEqual(byte[] a, byte[] b)
  {
    int aLength = a.length;
    if (aLength != b.length) {
      return false;
    }
    for (int i = 0; i < aLength; i++) {
      if (a[i] != b[i]) {
        return false;
      }
    }
    return true;
  }

  private static String toString(byte[] ba, int offset, int length)
  {
    char[] buf = new char[length * 2];
    int i = offset;
    for (int j = 0; i < offset + length;)
    {
      int k = ba[(i++)];
      buf[(j++)] = HEX_DIGITS[(k >>> 4 & 0xF)];
      buf[(j++)] = HEX_DIGITS[(k & 0xF)];
    }
    return new String(buf);
  }

  private static byte[] toByte(String encStr)
  {
    char[] buf = encStr.toCharArray();
    byte[] result = new byte[buf.length / 2];
    int resultIndex = 0;
    for (int i = 0; i < buf.length; i += 2)
    {
      char ch = buf[i];
      byte firstByte = 0;
      byte secondByte = 0;
      for (int j = 0; j < HEX_DIGITS.length; j++) {
        if (ch == HEX_DIGITS[j])
        {
          firstByte = HEX_BYTES[j];
          break;
        }
      }
      ch = buf[(i + 1)];
      for (int k = 0; k < HEX_DIGITS.length; k++) {
        if (ch == HEX_DIGITS[k])
        {
          secondByte = HEX_BYTES[k];
          break;
        }
      }
      byte shiftedFirstByte = (byte)(firstByte << 4 & 0xF0);
      byte shiftedSecondByte = (byte)(secondByte & 0xF);
      byte mergedByte = (byte)(shiftedFirstByte | shiftedSecondByte);
      result[(resultIndex++)] = mergedByte;
    }
    return result;
  }
}
Was it helpful?

Solution 2

Found out how to call it from another class.

<cfscript>
factory = createObject("java","coldfusion.server.ServiceFactory");
request.sqlexecutive = factory.getDataSourceService();
newPass = request.sqlexecutive.encryptPassword("p455w0rd");
</cfscript>

<cfoutput>Encrypted: #newPass#<br></cfoutput>

OTHER TIPS

It's a protected method. You can't call it.

Reading: "Controlling Access to Members of a Class"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top