Created
February 23, 2015 17:59
-
-
Save mrg/b9781ffcfd36e418e891 to your computer and use it in GitHub Desktop.
AES Password Encoder for Cayenne Models
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 javax.crypto.Cipher; | |
import javax.crypto.spec.SecretKeySpec; | |
import org.apache.cayenne.conf.PasswordEncoding; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
/** | |
* @author mrg | |
*/ | |
public class AESPasswordEncoder implements PasswordEncoding | |
{ | |
final static private int cipherKeyLength = 16; | |
final static private int cipherKeyOffset = 0; | |
final static private String cipherProvider = "AES"; | |
/* | |
* | |
*/ | |
public String decodePassword(String encodedPassword, String key) | |
{ | |
Cipher decryptionCipher = null; | |
SecretKeySpec keySpecification = null; | |
key = fixKey(key); | |
keySpecification = new SecretKeySpec(key.getBytes(), cipherKeyOffset, cipherKeyLength, cipherProvider); | |
try | |
{ | |
decryptionCipher = Cipher.getInstance(cipherProvider); | |
decryptionCipher.init(Cipher.DECRYPT_MODE, keySpecification); | |
return new String(decryptionCipher.doFinal(new BASE64Decoder().decodeBuffer(encodedPassword))); | |
} | |
catch (Exception e) | |
{ | |
// There was an exception getting the cipher -- report the error and | |
// fall back to plain text (assumption is that encoding failed, too). | |
e.printStackTrace(); | |
return encodedPassword; | |
} | |
} | |
/* | |
* | |
*/ | |
public String encodePassword(String normalPassword, String key) | |
{ | |
Cipher encryptionCipher = null; | |
SecretKeySpec keySpecification = null; | |
key = fixKey(key); | |
keySpecification = new SecretKeySpec(key.getBytes(), cipherKeyOffset, cipherKeyLength, cipherProvider); | |
try | |
{ | |
encryptionCipher = Cipher.getInstance(cipherProvider); | |
encryptionCipher.init(Cipher.ENCRYPT_MODE, keySpecification); | |
return new BASE64Encoder().encode(encryptionCipher.doFinal(normalPassword.getBytes())); | |
} | |
catch (Exception e) | |
{ | |
// There was an exception getting the cipher -- report the error and | |
// fall back to plain text (assumption is that encoding failed, too). | |
e.printStackTrace(); | |
return normalPassword; | |
} | |
} | |
private String fixKey(String key) | |
{ | |
if (key == null) | |
key = ""; | |
else | |
key = key.trim(); | |
while (key.length() < cipherKeyLength) | |
key += getClass().getName(); | |
return key; | |
} | |
private void runTests() | |
{ | |
String e, d, text = "myTestPassword!@#$%^"; | |
System.out.println("Test password: " + text); | |
System.out.println(); | |
// Test with null for the AES key | |
e = encodePassword(text, null); | |
d = decodePassword(e, null); | |
System.out.println("Encrypted: " + e); | |
if (d.equals(text)) | |
System.out.println("Test with null key passed."); | |
else | |
System.out.println("**** TEST WITH NULL KEY FAILED."); | |
// Test with "" for the AES key | |
e = encodePassword(text, ""); | |
d = decodePassword(e, ""); | |
System.out.println("Encrypted: " + e); | |
if (d.equals(text)) | |
System.out.println("Test with empty key passed."); | |
else | |
System.out.println("**** TEST WITH EMPTY KEY FAILED."); | |
// Test with sub-16 character AES key | |
e = encodePassword(text, "abcd1234efgh"); | |
d = decodePassword(e, "abcd1234efgh"); | |
System.out.println("Encrypted: " + e); | |
if (d.equals(text)) | |
System.out.println("Test with sub-16 character key passed."); | |
else | |
System.out.println("**** TEST WITH SUB-16 CHARACTER KEY FAILED."); | |
// Test with 16-character AES key | |
e = encodePassword(text, "abcd1234efgh5678"); | |
d = decodePassword(e, "abcd1234efgh5678"); | |
System.out.println("Encrypted: " + e); | |
if (d.equals(text)) | |
System.out.println("Test with 16-character key passed."); | |
else | |
System.out.println("**** TEST WITH 16-CHARACTER KEY FAILED."); | |
// Test with 16-plus character AES key | |
e = encodePassword(text, "abcd1234efgh5678ijkl"); | |
d = decodePassword(e, "abcd1234efgh5678ijkl"); | |
System.out.println("Encrypted: " + e); | |
if (d.equals(text)) | |
System.out.println("Test with 16-plus character key passed."); | |
else | |
System.out.println("**** TEST WITH 16-PLUS CHARACTER KEY FAILED."); | |
} | |
private static void printUsage() | |
{ | |
System.out.println("Usage:"); | |
System.out.println(" " + AESPasswordEncoder.class.getName() + " -d text-to-decrypt [key]"); | |
System.out.println(" " + AESPasswordEncoder.class.getName() + " -e text-to-encrypt [key]"); | |
System.out.println(" " + AESPasswordEncoder.class.getName() + " -t (run tests)"); | |
System.out.println(""); | |
System.out.println(" The key should be 16 characters in length, but this is not required."); | |
} | |
public static void main(String[] args) | |
{ | |
if (args.length < 1) | |
{ | |
printUsage(); | |
return; | |
} | |
AESPasswordEncoder encoder = new AESPasswordEncoder(); | |
String flag = args[0]; | |
String text = null; | |
String key = null; | |
if (args.length >= 2) | |
text = args[1]; | |
if (args.length == 3) | |
key = args[2]; | |
if (flag.equals("-d") && args.length >= 2) | |
System.out.println(encoder.decodePassword(text, key)); | |
else if (flag.equals("-e") && args.length >= 2) | |
System.out.println(encoder.encodePassword(text, key)); | |
else if (flag.equals("-t") && args.length == 1) | |
encoder.runTests(); | |
else | |
printUsage(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment