Created
January 21, 2014 19:58
-
-
Save anonymous/8547206 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.codec.binary.Hex; | |
import javax.crypto.Cipher; | |
import javax.crypto.SecretKeyFactory; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.PBEKeySpec; | |
import javax.crypto.spec.SecretKeySpec; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.SecureRandom; | |
import java.security.spec.InvalidKeySpecException; | |
import java.security.spec.KeySpec; | |
public class MyCrypto { | |
public static final String KEY_ENC_ALGO = "AES"; | |
public static final String CIPHER_ALGO = "AES/CBC/PKCS5Padding"; | |
public MyCrypto() { | |
} | |
public static String encrypt(String data, String password) throws Exception { | |
final byte[] salt = generateSalt(); | |
// Take the password, and run it through PBKDF2 (HMAC-SHA1) 2000 times. Return a 256-bit key. | |
final byte[] key = deriveSecureKey(password, salt, 256, 2000); | |
final Cipher cipher = Cipher.getInstance(CIPHER_ALGO); | |
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, KEY_ENC_ALGO)); | |
final byte[] encryptedBytes = cipher.doFinal(data.getBytes()); | |
// Stitch our encrypted String, salt and IV (using Apache Codec Hex to convert Bytes to String) | |
StringBuilder packet = new StringBuilder(); | |
packet.append(Hex.encodeHex(encryptedBytes)); | |
packet.append("$"); | |
packet.append(Hex.encodeHex(salt)); | |
packet.append("$"); | |
packet.append(Hex.encodeHex(cipher.getIV())); | |
return packet.toString(); | |
} | |
public static String decrypt(String data, String password) throws Exception { | |
// Take our encoded string and split it apart. | |
String[] parts = data.split("\\$"); | |
final byte[] encryptedBytes = Hex.decodeHex(parts[0].toCharArray()); | |
final byte[] salt = Hex.decodeHex(parts[1].toCharArray()); | |
final byte[] iv = Hex.decodeHex(parts[2].toCharArray()); | |
// Recalculate our key using the same parameters used during encryption | |
final byte[] key = deriveSecureKey(password, salt, 256, 2000); | |
final Cipher cipher = Cipher.getInstance(CIPHER_ALGO); | |
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, KEY_ENC_ALGO), new IvParameterSpec(iv)); | |
final byte[] decryptedBytes = cipher.doFinal(encryptedBytes); | |
return new String(decryptedBytes); | |
} | |
public static byte[] deriveSecureKey(String password, byte[] salt, int derivedKeyLength, int iterations) | |
throws NoSuchAlgorithmException, InvalidKeySpecException { | |
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength); | |
return SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec).getEncoded(); | |
} | |
public static byte[] generateSalt() throws NoSuchAlgorithmException { | |
SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); | |
byte[] salt = new byte[8]; | |
random.nextBytes(salt); | |
return salt; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment