1

I basically need to decrypt a password I retrieve from a server encrypted with Rijndael, I have never worked with encrypting/decrypting before and I am completely lost. I found somewhere in this web that Java has some methods implemented without need of external libraries to do so but I didn't get it. The only thing I need is the decrypt since I won't be writing back into the server anyways.

Any idea on how to do it or where I could find documentation about it?

I don't know if this code, taken from an answer here is what I am looking for, I don't understand much of it, as I said, I've never worked with this kind of stuff before:

byte[] sessionKey = null; //Where you get this from is beyond the scope of this post
byte[] iv = null ; //Ditto
byte[] plaintext = null; //Whatever you want to encrypt/decrypt
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//You can use ENCRYPT_MODE or DECRYPT_MODE
cipher.calling init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext);

Thanks in advance.

Community
  • 1
  • 1
Heartcroft
  • 1,672
  • 2
  • 19
  • 31
  • Looks like it is the right piece of code. Have you tried to use it? I guess it should be `cipher.init(Cipher.DECRYPT_MODE, ...` and I don't know either where you get your session key & initialization vector (iv) from or if `"AES/CBC/PKCS5Padding"` is the right mode. But if you figure that out all you have to do is to fill the encrypted password into `plaintext` and you get it decrypted in `cyphertext` in the end. – zapl Apr 27 '12 at 21:11
  • I didn't try it out mainly because I didn't know where to place the password retrieved, gonna try it now like you said. Thanks. – Heartcroft Apr 27 '12 at 21:22
  • @zapl apparently it can't resolve the .calling and can't find the init() method. Any idea? – Heartcroft Apr 27 '12 at 22:02
  • I guess the `.calling ` part was a mistake and it is `cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));` – zapl Apr 27 '12 at 22:32
  • @zapl You are right in that, I actually figured it out myself a couple of minute ago, sadly I can't try if the decrypt works cause the server is behaving stupid at the moment, need to solve that first. Thanks anyway. – Heartcroft Apr 27 '12 at 22:50
  • @zapl Btw, any idea on what sessionkey and iv are? – Heartcroft Apr 27 '12 at 23:43
  • You need to know *how it was encrypted*, specifically the mode and padding, otherwise nobody can give the correct answer. – Maarten Bodewes May 10 '12 at 01:26

1 Answers1

0

Here is a Simple Crypto utility class that might be of help to you. Its based on the code written by ferenc.hechler posted at the following url : http://www.androidsnippets.com/encryptdecrypt-strings I have made some changes to it to fit my needs.

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class SimpleCrypto {

    private static final int KEY_SIZE = 128;

    public static String encrypt(String seed, String cleartext) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        final byte[] rawKey = getRawKey(seed.getBytes());
        final byte[] result = encrypt(rawKey, cleartext.getBytes());
        return bin2hex(result);
    }

    public static String decrypt(String seed, String encrypted) throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
        final byte[] rawKey = getRawKey(seed.getBytes());
        final byte[] enc = toByte(encrypted);
        final byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }

    public static String decrypt(String seed, byte[] encrypted) throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
        final byte[] rawKey = getRawKey(seed.getBytes());
        final byte[] result = decrypt(rawKey, encrypted);
        return new String(result);
    }

    private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException {
        final KeyGenerator kgen = KeyGenerator.getInstance("AES");
        final SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(KEY_SIZE, sr); // 192 and 256 bits may not be available
        final SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

    public static byte[] encrypt(byte[] raw, byte[] clear) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        final byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    public static byte[] decrypt(byte[] raw, byte[] encrypted) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        final byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    public static String toHex(String txt) {
        return bin2hex(txt.getBytes());
    }

    public static String fromHex(String hex) {
        return new String(toByte(hex));
    }

    public static byte[] toByte(String hexString) {
        final int len = hexString.length() / 2;
        final byte[] result = new byte[len];
        for (int i = 0; i < len; i++) {
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
        }
        return result;
    }

    public static byte[] getHash(String str) {
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        digest.reset();
        return digest.digest(str.getBytes());
    }

    static String bin2hex(byte[] data) {
        return String.format("%0" + (data.length * 2) + "X", new BigInteger(1, data));
    }
}

Here is how you would use it to decrypt something :

    final String ssid = "MY_WIFI_SSID";
    final String encWifiKey = "myEncryptedWifiKeyString";

    String wifiKey = "";
    try {
        wifiKey = new String(SimpleCrypto.decrypt(SimpleCrypto.getHash(ssid), Base64.decode(encWifiKey, Base64.DEFAULT)));
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }
Akos Cz
  • 12,711
  • 1
  • 37
  • 32
  • Haven't tried it but, one thing I don't understand is in every single approach I see about this, the result seems to be a byte type. After decrypting shouldn't I have a String? I mean, what the user would enter is captured as a String so... – Heartcroft Apr 27 '12 at 23:50
  • Encryption (or at least block ciphers) normally only work on bytes. So the String needs to be converted to bytes before encryption and reversed back after decryption. Normally this is performed by using a specific character encoding, such as UTF-8. Use `new String(byte[], Charset.forName("UTF-8"))` to accomplish this for the most used UTF-8 encoding. – Maarten Bodewes May 10 '12 at 01:21
  • 1
    Don't use this example! I've already encountered this example many times, and it does about *everything* wrong that can be done wrong. Akos Cz, don't post code you don't understand. – Maarten Bodewes May 10 '12 at 01:24
  • Like I said, it fits my needs and it might be helpful to the original poster. You might consider providing an example that you feel does everything right :P – Akos Cz May 10 '12 at 16:44