views:

1429

answers:

5

How do I encrypt/decrypt a string of text using 3DES in java?

+1  A: 

From an old code:

    public void testSymCypher(SecretKey k, String str)
        throws BadPaddingException, IllegalBlockSizeException,
        InvalidAlgorithmParameterException, InvalidKeyException,
        NoSuchAlgorithmException, NoSuchPaddingException
{
    Cipher cip = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    cip.init(Cipher.ENCRYPT_MODE,k);
    byte[] ciphered = cip.doFinal(str.getBytes());
    byte iv[] = cip.getIV();

    // printing the ciphered string
    printHexadecimal(ciphered);

    IvParameterSpec dps = new IvParameterSpec(iv);
    cip.init(Cipher.DECRYPT_MODE,k,dps);
    byte[] deciphered = cip.doFinal(ciphered);

    // printing the deciphered string
    printHexadecimal(deciphered);
}

Notice than other usage of DESede are available in Java JDK 6:

  • DESede/CBC/NoPadding (168)
  • DESede/CBC/PKCS5Padding (168)

There is also ECB mode available (but be carreful to not use it twice !!), you don't need to use iv part in this case:

  • DESede/ECB/NoPadding (168)
  • DESede/ECB/PKCS5Padding (168)

To generate key for DESede:

    KeyGenerator generatorDes = KeyGenerator.getInstance("DESede");
    SecretKey skaes = generatorDes.generateKey();

Finally I recommand reading this document from SUN if you need to work on Java and Cryptography

Kartoch
This code gives me a java.security.InvalidKeyException: Invalid key length: 8 bytes at com.sun.crypto.provider.DESedeCipher.engineGetKeySize(DashoA13*..)
ScArcher2
I think it's because I made a mistake with KeyGenerator: it is DESede and not DES. If you use your own key, check your key size (it seems related to the kind of 3DES key you use. Because I don't know too much about it, please refer to the wikipedia page of 3DES).
Kartoch
+1  A: 

We use this little helper class for password-based DES encryption from String to Hex String and back - not sure how to get this working with 3DES though:

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

public class DesHelper {
    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DesHelper.class);

    static final byte[] SALT = { (byte) 0x09, /* snip - randomly chosen but static salt*/ };
    static final int ITERATIONS = 11;

    private Cipher _ecipher;
    private Cipher _dcipher;

    public DesHelper(final String passphrase) {
        try {
            final PBEParameterSpec params = new PBEParameterSpec(SALT, ITERATIONS);

            final KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
            final SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
                    .generateSecret(keySpec);

            _ecipher = Cipher.getInstance(key.getAlgorithm());
            _dcipher = Cipher.getInstance(key.getAlgorithm());
            _ecipher.init(Cipher.ENCRYPT_MODE, key, params);
            _dcipher.init(Cipher.DECRYPT_MODE, key, params);

        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String encrypt(final String string) {
        try {
            // Encode the string into bytes using utf-8
            final byte[] bytes = string.getBytes("UTF-8");

            // Encrypt
            final byte[] enc = _ecipher.doFinal(bytes);

            // Encode bytes to base64 to get a string
            return bytesToHex(enc);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String decrypt(final String str) {
        try {
            // Decode base64 to get bytes
            final byte[] dec = hexToBytes(str);

            // Decrypt
            final byte[] utf8 = _dcipher.doFinal(dec);

            // Decode using utf-8
            return new String(utf8, "UTF8");
        } catch (final Exception e) {
            log.info("decrypting string failed: " + str + " (" + e.getMessage() + ")");
            return null;
        }
    }

    private static String bytesToHex(final byte[] bytes) {
        final StringBuilder buf = new StringBuilder(bytes.length * 2);
        for (final byte b : bytes) {
            final String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                buf.append("0");
            }
            buf.append(hex);
        }
        return buf.toString();
    }

    private static byte[] hexToBytes(final String hex) {
        final byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
        }
        return bytes;
    }
}

You would use this class like this:

public static void main(final String[] args) {
    final DesHelper h = new DesHelper("blabla");
    System.out.println(h.decrypt(h.encrypt("foobar")));
}
sfussenegger
A: 

I found my answer. Duplicate question that didn't show up when I asked this one.

http://stackoverflow.com/questions/20227/how-do-i-use-3des-encryption-decryption-in-java

ScArcher2
A: 

I wrote an article on this sometimes back. Please visit the following link in my blog that has a working, completed code with explanations and diagram.

View My Triple DES Encryption Article, Code Here

Hopefully you will find it helpful.

Kushal Paudyal
A: 

You may also consider using a stream cipher (e.g., OFB or CTR mode on top of a 3DES block encryption), so that you don't have to deal with padding the string to a multiple of the cipher blocksize.

Loadmaster