Java using AES 256 and 128 Symmetric-key encryption
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.i开发者_如何学Pythonnit(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 ?
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.
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;
}
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);
...
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.
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;
}
}
精彩评论