Java using AES 256 and 128 Symmetric-key encryption
Asked Answered
E

5

15

I am new in cipher technology. I found this code to do Symmetric Encryption.

byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);

Its working. Here I can use my own password. And thats what exactly I needed. But I dont know how to do 128 or 256 Symmetric Enctryption. How can I use 128 and 256 key into my code ?

Enamor answered 30/6, 2011 at 17:9 Comment(4)
I really don't know, but I think using a key of 256 bytes will do the job.Andie
actually only 16 bytes (128 bits) key is working into my code.Enamor
what is "not working" with bigger keys? Do you get an exception? which one? what's its message and stack trace?Riser
perhaps because I dont have JCEEnamor
S
18

Whether AES uses 128 or 256 bit mode depends on size of your key, which must be 128 or 256 bits long. Typically you don't use your password as a key, because passwords rarely have exact length as you need. Instead, you derive encryption key from your password by using some key derivation function.

Very simple example: take MD5 of your password to get 128-bit key. If you want 256-bit key, you can use SHA-256 to get 256-bit hash of your password. Key-derivation functions usually run this hashing several hundreds time and use extra salt as well. Check out http://en.wikipedia.org/wiki/Key_derivation_function for details.

Also note: to run encryption stronger than 128-bit you will need to download and install 'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6' from http://www.oracle.com/technetwork/java/javase/downloads/index.html.

Sodomy answered 30/6, 2011 at 17:39 Comment(8)
MD5? Did I wake up in 1996 this morning? The SHA family has algorithms that produce 128, 256, 348, and 512 bit hashes.Unrestraint
@Peter: it was just an quick example how to get 128-bit key computed from password. If your password has less than 16 bytes, you may as well just pad it to 16 bytes. You're nitpicking unimportant details. (Anyway I've updated my answer to say to use SHA-256 to get 256-bit key from password)Sailcloth
@Peter, hahaha, yeah I just hate seeing MD5 in anything but legacy code, and don't think it should be recommended to beginners; It's been long since broken.Unrestraint
@Peter: :-) it's "broken" for some uses ... but in this case, it's not really important what hashing algorithm you choose. You want to protect your key regardless of how you get it. It's not like your key (md5 hash of password) was public and someone wants to know your password. Once somebody has your key (md5 hash from my example) you are doomed. And MD5 has little to do with it.Sailcloth
@Peter: I guess what I'm trying to say is that MD5 is still fine for many purposes. As a cryptography hash, it has its weaknesses, but that doesn't kills it as a hashing algorithm. Now I shut up, as we are quite off-topic.Sailcloth
Thanks Peter. Your answer was really helpful.Enamor
There's nothing wrong with using MD5 as Peter Stibrany described it. MD5 has vulnerabilities that make it unsuitable for a lot of situations, but this isn't one of them. In general, though, deriving keys from passwords should use a key derivation algorithm like PBKDF2 (which uses SHA-1 by default), bcrypt, or scrypt.Greene
I edited this comment to strikethrough the suggestion to use 128bit md5Mesentery
S
8

The Answer for 128 bit

The following method is to encrypt a string (valueEnc) with AES encryption:

private static final String ALGORITHM = "AES"; 

public String encrypt(final String valueEnc, final String secKey) { 

    String encryptedVal = null;

    try {
        final Key key = generateKeyFromString(secKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.ENCRYPT_MODE, key);
        final byte[] encValue = c.doFinal(valueEnc.getBytes());
        encryptedVal = new BASE64Encoder().encode(encValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return encryptedVal;
}

The next method will decrypt the AES encrypted string (encryptedVal):

    public String decrypt(final String encryptedValue, final String secretKey) {

    String decryptedValue = null;

    try {

        final Key key = generateKeyFromString(secretKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.DECRYPT_MODE, key);
        final byte[] decorVal = new BASE64Decoder().decodeBuffer(encryptedValue);
        final byte[] decValue = c.doFinal(decorVal);
        decryptedValue = new String(decValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return decryptedValue;
}

The secKey is a 128-bit key, which is encoded in the BASE64Encoder. The BASE64Decoder in the following method generates an appropriate 128-bit key

private Key generateKeyFromString(final String secKey) throws Exception {
    final byte[] keyVal = new BASE64Decoder().decodeBuffer(secKey);
    final Key key = new SecretKeySpec(keyVal, ALGORITHM);
    return key;
}
Shayneshays answered 20/5, 2015 at 11:14 Comment(1)
You have forgotten to use an initialization vector, and you also did not specify the mode and padding of AES you want to use. While this is an answer to the question, be aware that this it is not a secure use of encryption.Slater
W
3

You can use a simple KeyGenerator object like this:

KeyGenerator generator = KeyGenerator.getInstance("AES/CTR/PKCS5PADDING");
generator.init(128);
SecretKey key = generator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
Wernick answered 30/6, 2011 at 17:30 Comment(0)
R
1

From Java's docs for Cipher.init(...):

public final void init(int opmode, Key key)

Throws: InvalidKeyException - if the given key is inappropriate for initializing this cipher, or if this cipher is being initialized for decryption and requires algorithm parameters that cannot be determined from the given key, or if the given key has a keysize that exceeds the maximum allowable keysize (as determined from the configured jurisdiction policy files).

To me, this means that, as Martijn Courteaux said in his comment, you should use a key of 256 bits (i.e. initialize the SecretKeySpec with a byte array containing 32 bytes), and the cipher will accept it and use it, or reject it and throw an exception if its size is not acceptable.

If you get an exception, it's probably because you have not installed the unlimited strength crypto files, (the default JDK install allows 128 bit keys as documented in this crypto spec document). Download unlimited strength crypto package here.

Riser answered 30/6, 2011 at 17:38 Comment(0)
S
0
public class CipherUtils
{
    private static byte[] key = {
            0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
    };//"thisIsASecretKey";

    public static String encrypt(String strToEncrypt)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
            return encryptedString;
        }
        catch (Exception e)
        {
           e.printStackTrace();
        }
        return null;
    }
}
Shayneshays answered 20/5, 2015 at 10:48 Comment(3)
I have a couple of questions. 1. That key is the only key that can be used to decrypt, right? (probably an obvious answer to that question - just making sure) 2. If the same data is encrypted using that same key -- two different times running the method--, does it render different encrypted bytes?Washedout
Well, I converted that code and figured it out the answers for myself. Also, it is interesting that the OWASP example (owasp.org/index.php/Using_the_Java_Cryptographic_Extensions ) directly mentions using the IV (initialization vector) but it isn't used in the code in this answer. Ce la vie.Washedout
Do not hard code a secret key. It will be trivially available to anyone who has access to the compiled code.Mesentery

© 2022 - 2024 — McMap. All rights reserved.