Search code examples
javablowfish

Why do forward slashes get stripped on Blowfish encryption?


Consider the following method that performs Blowfish encryption:

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

private static String encryptString(String value, String key)
{
    String encryptedString = "";
    if (value != null)
    {
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "Blowfish");
        try
        {
            Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS#5");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            encryptedString = new String(Hex.encodeHex(encrypted));
        }
        catch (Exception e)
        {
            // Show error
        }
    }
    return encryptedString;
}

The String that I want to encode contains forward slashes. When I try to encode for example "http://www.google.com/Foo", for some reason when I decode it, the forward slashes are stripped, e.g. "http:www.google.comFoo".

What could be a possible cause for this and how could this be prevented?


Solution

  • It's an error of the website (https://webnet77.net/cgi-bin/helpers/blowfish.pl) you're using to check the encrypted text.

    Try encrypting the text (http://www.google.com/Foo) on that site, and you'll see that it strips the slashes. Java doesn't.


    Other issues:

    • What is the value of the key parameter?

      If it is a hex encoding of the Blowfish key, then getBytes() is entirely wrong, since you need to hex decode it, rather than the code page conversion you're currently doing.

      SecretKeySpec needs a byte[] because a key is a binary value, and cannot be stored a plain text.

    • Blowfish/ECB/PKCS#5 is not a valid cipher in JDK.

      Blowfish/ECB/PKCS5PADDING is.

    • If your value parameter can ever contain anything other than plain ASCII, then value.getBytes() is inadequate. You should always specify the code page when converting a string into bytes.

      You can specify "US-ASCII" to enforce ASCII only, or specify the code page required by the server, but "UTF-8" is generally a good choice.