user1349407
user1349407

Reputation: 622

Java - 2 Bytes character encryption via BlowFish cipher

I am trying to develop symmetric encryption software which provides 2-bytes character encoding.

however, the following code cannot encrypt 2-bytes character and I don't know why.

(the code works properly with English)


package com.messagesecretpro;
import gnu.crypto.cipher.Blowfish;
import gnu.crypto.util.Base64;
import java.io.*;
import java.lang.reflect.Array;

public class BlowfishCipher {
    public static String encrypt(String cookieValue, String key) {
        byte[] plainText;
        byte[] encryptedText;

        Blowfish blowfish = new Blowfish();
        // create a key
        // String key = "zzforexamplekeytext";
        byte[] keyBytes = key.getBytes();
        Object keyObject = blowfish.makeKey(keyBytes, 8);

        // make the length of the text a multiple of the block size
        if ((cookieValue.length() % 8) != 0) {
            while ((cookieValue.length() % 8) != 0) {
                cookieValue += " ";
            }
        }

        // initialize byte arrays for plain/encrypted text
        plainText = cookieValue.getBytes();
        encryptedText = new byte[cookieValue.length()];

        // encrypt text in 8-byte chunks
        for (int i = 0; i < Array.getLength(plainText); i += 8) {
            blowfish.encrypt(plainText, i, encryptedText, i, keyObject, 8);
        }
        String encryptedString = Base64.encode(encryptedText);
        return encryptedString;
    }

    public static String decrypt(String cookieValue, String key)
            throws UnsupportedEncodingException {

        byte[] encryptedText;
        byte[] decryptedText;
        Blowfish blowfish = new Blowfish();

        // create the key
        // String key = "zzforexamplekeytext";
        byte[] keyBytes = key.getBytes();
        Object keyObject = blowfish.makeKey(keyBytes, 8);

        // make the length of the string a multiple of
        // the block size
        if ((cookieValue.length() % 8) != 0) {
            while ((cookieValue.length() % 8) != 0) {
                cookieValue += " ";
            }
        }

        // initialize byte arrays that will hold encrypted/decrypted

        encryptedText = Base64.decode(cookieValue);
        decryptedText = new byte[cookieValue.length()];

        // Iterate over the byte arrays by 8-byte blocks and decrypt.
        for (int i = 0; i < Array.getLength(encryptedText); i += 8) {
            blowfish.decrypt(encryptedText, i, decryptedText, i, keyObject, 8);
        }

        String decryptedString = new String(decryptedText);
        return decryptedString;
    }
}

Upvotes: 0

Views: 772

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

You should read the documentation; the Blowfish class implements a block cipher, not a block cipher mode of operation such as ECB or CBC, nor padding. So you can only use the given encrypt method for blocks of data (8 bytes).

You are trying to iterate (using the for next loop) encrypting each byte (or, currently, overlapping blocks). If the input of the encrypt method however does not contain a full block to encrypt (from the given offset) you will get an index out of bounds exception.

So:

  1. Use a blockcipher using a good mode of operation and - when required for the mode of operation - padding;
  2. Don't use cryptographic libraries or algorithms that have been abandoned ages ago.

Bruce Schneier, the author of the algorithm, has adviced against using this cipher ages ago. Although it is still considered secure, the block size of 8 bytes makes it relatively insecure in most modes of operation.

Preferably you should be using AES in an authenticated mode of operation such as GCM, using a unique nonce / key combination. Often it is preferable to use a higher level protocol / container format instead so that you don't have to (overly) rely on yourself to make the ciphertext secure.

Upvotes: 2

Related Questions