原文地址http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html
2000年9月开始,nist开始支持fips,来取代已经过时的des(Data Enryption Strandard).
1 什么是AES
AES是一种对称的私钥加密技术。它支持128,192,256位加密。
2 AES和Java
从j2se1.4.2开始,集成了JCE包。
现在的java支持128位key的加密。(下面的程序也是以128位为例讲解的)
3 如何使用JCE
例
- import java.security.*;
- import javax.crypto.*;
- import javax.crypto.spec.*;
- import java.io.*;
-
-
-
-
-
-
-
-
- public class AES {
-
-
-
-
-
-
-
- public static String asHex (byte buf[]) {
- StringBuffer strbuf = new StringBuffer(buf.length * 2);
- int i;
-
- for (i = 0; i < buf.length; i++) {
- if (((int) buf[i] & 0xff) < 0x10)
- strbuf.append("0");
-
- strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
- }
-
- return strbuf.toString();
- }
-
- public static void main(String[] args) throws Exception {
-
- String message="This is just an example";
-
-
-
- KeyGenerator kgen = KeyGenerator.getInstance("AES");
- kgen.init(128);
-
-
-
- SecretKey skey = kgen.generateKey();
- byte[] raw = skey.getEncoded();
-
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
-
-
-
-
- Cipher cipher = Cipher.getInstance("AES");
-
- cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
-
- byte[] encrypted =
- cipher.doFinal((args.length == 0 ?
- "This is just an example" : args[0]).getBytes());
- System.out.println("encrypted string: " + asHex(encrypted));
-
- cipher.init(Cipher.DECRYPT_MODE, skeySpec);
- byte[] original =
- cipher.doFinal(encrypted);
- String originalString = new String(original);
- System.out.println("Original string: " +
- originalString + " " + asHex(original));
- }
- }
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
/**
* This program generates a AES key, retrieves its raw bytes, and
* then reinstantiates a AES key from the key bytes.
* The reinstantiated key is used to initialize a AES cipher for
* encryption and decryption.
*/
public class AES {
/**
* Turns array of bytes into string
*
* @param buf Array of bytes to convert to hex string
* @return Generated hex string
*/
public static String asHex (byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String[] args) throws Exception {
String message="This is just an example";
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted =
cipher.doFinal((args.length == 0 ?
"This is just an example" : args[0]).getBytes());
System.out.println("encrypted string: " + asHex(encrypted));
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original =
cipher.doFinal(encrypted);
String originalString = new String(original);
System.out.println("Original string: " +
originalString + " " + asHex(original));
}
}
4 更强壮的加密
kgen.init(256); // 128 and 192 bits also available
按照原文提示的地址可以更新下一个包,然后稍微修改下加密位数就可以了。不过jdk1.4默认只支持128位的加密,实际上,作者也建议同时利用SSL,比单独一味强调加密位数效果要好。
5 同时使用SSL和AES
server端
- import java.io.*;
- import java.security.*;
- import javax.net.ssl.*;
-
-
- import java.util.regex.*;
-
-
- public class HelloServerSSL {
- public static void main(String[] args) {
- SSLServerSocket s;
-
-
-
- String patternString = "AES.*256";
- Pattern pattern = Pattern.compile(patternString);
- Matcher matcher;
- boolean matchFound;
-
- try {
- SSLServerSocketFactory sslSrvFact =
- (SSLServerSocketFactory)
- SSLServerSocketFactory.getDefault();
- s =(SSLServerSocket)sslSrvFact.createServerSocket(8181);
-
- SSLSocket in = (SSLSocket)s.accept();
-
-
- String str[]=in.getSupportedCipherSuites();
-
- int len = str.length;
- String set[] = new String[len];
-
- int j=0, k = len-1;
- for (int i=0; i < len; i++) {
-
-
- matcher = pattern.matcher(str[i]);
- matchFound = matcher.find();
-
- if (matchFound)
- set[j++] = str[i];
- else
- set[k--] = str[i];
- }
-
- in.setEnabledCipherSuites(set);
-
- str=in.getEnabledCipherSuites();
-
- System.out.println("Available Suites after Set:");
- for (int i=0; i < str.length; i++)
- System.out.println(str[i]);
- System.out.println("Using cipher suite: " +
- (in.getSession()).getCipherSuite());
-
- PrintWriter out = new PrintWriter (in.getOutputStream(),
- true);
- out.println("Hello on a SSL socket");
- in.close();
- } catch (Exception e) {
- System.out.println("Exception" + e);
- }
- }
- }
import java.io.*;
import java.security.*;
import javax.net.ssl.*;
import java.util.regex.*;
public class HelloServerSSL {
public static void main(String[] args) {
SSLServerSocket s;
// Pick all AES algorithms of 256 bits key size
String patternString = "AES.*256";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher;
boolean matchFound;
try {
SSLServerSocketFactory sslSrvFact =
(SSLServerSocketFactory)
SSLServerSocketFactory.getDefault();
s =(SSLServerSocket)sslSrvFact.createServerSocket(8181);
SSLSocket in = (SSLSocket)s.accept();
String str[]=in.getSupportedCipherSuites();
int len = str.length;
String set[] = new String[len];
int j=0, k = len-1;
for (int i=0; i < len; i++) {
// Determine if pattern exists in input
matcher = pattern.matcher(str[i]);
matchFound = matcher.find();
if (matchFound)
set[j++] = str[i];
else
set[k--] = str[i];
}
in.setEnabledCipherSuites(set);
str=in.getEnabledCipherSuites();
System.out.println("Available Suites after Set:");
for (int i=0; i < str.length; i++)
System.out.println(str[i]);
System.out.println("Using cipher suite: " +
(in.getSession()).getCipherSuite());
PrintWriter out = new PrintWriter (in.getOutputStream(),
true);
out.println("Hello on a SSL socket");
in.close();
} catch (Exception e) {
System.out.println("Exception" + e);
}
}
}
client端
- import java.io.*;
- import java.security.*;
- import javax.net.ssl.*;
-
-
- import java.util.regex.*;
-
-
- public class HelloClientSSL {
- public static void main(String[] args) {
-
-
-
- String patternString = "AES.*256";
- Pattern pattern = Pattern.compile(patternString);
- Matcher matcher;
- boolean matchFound;
-
- try {
-
- SSLSocketFactory sslFact =
- (SSLSocketFactory)SSLSocketFactory.getDefault();
- SSLSocket s =
- (SSLSocket)sslFact.createSocket(args.length == 0 ?
- "127.0.0.1" : args[0], 8181);
-
- String str[]=s.getSupportedCipherSuites();
-
- int len = str.length;
- String set[] = new String[len];
-
- int j=0, k = len-1;
- for (int i=0; i < len; i++) {
- System.out.println(str[i]);
-
-
- matcher = pattern.matcher(str[i]);
- matchFound = matcher.find();
-
- if (matchFound)
- set[j++] = str[i];
- else
- set[k--] = str[i];
- }
-
- s.setEnabledCipherSuites(set);
-
- str=s.getEnabledCipherSuites();
-
- System.out.println("Available Suites after Set:");
- for (int i=0; i < str.length; i++)
- System.out.println(str[i]);
-
- OutputStream out = s.getOutputStream();
- BufferedReader in = new BufferedReader (
- new InputStreamReader(s.getInputStream()));
-
- String mesg = in.readLine();
- System.out.println("Socket message: " + mesg);
- in.close();
- } catch (Exception e) {
- System.out.println("Exception" + e);
- }
- }
- }
import java.io.*;
import java.security.*;
import javax.net.ssl.*;
import java.util.regex.*;
public class HelloClientSSL {
public static void main(String[] args) {
// Pick all AES algorithms of 256 bits key size
String patternString = "AES.*256";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher;
boolean matchFound;
try {
SSLSocketFactory sslFact =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket s =
(SSLSocket)sslFact.createSocket(args.length == 0 ?
"127.0.0.1" : args[0], 8181);
String str[]=s.getSupportedCipherSuites();
int len = str.length;
String set[] = new String[len];
int j=0, k = len-1;
for (int i=0; i < len; i++) {
System.out.println(str[i]);
// Determine if pattern exists in input
matcher = pattern.matcher(str[i]);
matchFound = matcher.find();
if (matchFound)
set[j++] = str[i];
else
set[k--] = str[i];
}
s.setEnabledCipherSuites(set);
str=s.getEnabledCipherSuites();
System.out.println("Available Suites after Set:");
for (int i=0; i < str.length; i++)
System.out.println(str[i]);
OutputStream out = s.getOutputStream();
BufferedReader in = new BufferedReader (
new InputStreamReader(s.getInputStream()));
String mesg = in.readLine();
System.out.println("Socket message: " + mesg);
in.close();
} catch (Exception e) {
System.out.println("Exception" + e);
}
}
}
运行结果
Available Suites after
Set:TLS_RSA_WITH_AES_256_CBC_SHATLS_DHE_RSA_WITH_AES_256_CBC_SHATLS_DHE_DSS_WITH_AES_256_CBC_SHATLS_DH_anon_WITH_AES_256_CBC_SHASSL_DH_anon_EXPORT_WITH_DES40_CBC_SHASSL_DH_anon_EXPORT_WITH_RC4_40_MD5SSL_DH_anon_WITH_DES_CBC_SHASSL_DH_anon_WITH_3DES_EDE_CBC_SHATLS_DH_anon_WITH_AES_128_CBC_SHASSL_DH_anon_WITH_RC4_128_MD5SSL_RSA_WITH_NULL_SHASSL_RSA_WITH_NULL_MD5SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHASSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHASSL_RSA_EXPORT_WITH_DES40_CBC_SHASSL_RSA_EXPORT_WITH_RC4_40_MD5SSL_DHE_DSS_WITH_DES_CBC_SHASSL_DHE_RSA_WITH_DES_CBC_SHASSL_RSA_WITH_DES_CBC_SHASSL_DHE_DSS_WITH_3DES_EDE_CBC_SHASSL_DHE_RSA_WITH_3DES_EDE_CBC_SHASSL_RSA_WITH_3DES_EDE_CBC_SHATLS_DHE_DSS_WITH_AES_128_CBC_SHATLS_DHE_RSA_WITH_AES_128_CBC_SHATLS_RSA_WITH_AES_128_CBC_SHASSL_RSA_WITH_RC4_128_SHASSL_RSA_WITH_RC4_128_MD5Using
cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
别人的例子
-
-
-
-
- import javax.crypto.Cipher;
- import javax.crypto.KeyGenerator;
- import java.security.Key;
-
-
-
-
- public class PrivateExample{
- public static void main(String[] args) throws Exception{
-
- byte[] plainText="12345678".getBytes();
-
-
- System.out.println("\nStart generate AES key");
- KeyGenerator keyGen=KeyGenerator.getInstance("AES");
- keyGen.init(128);
- Key key=keyGen.generateKey();
- System.out.println("Finish generating AES key");
-
-
- Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
- System.out.println("\n"+cipher.getProvider().getInfo());
-
-
- System.out.println("\nStart encryption:");
- cipher.init(Cipher.ENCRYPT_MODE,key);
- byte[] cipherText=cipher.doFinal(plainText);
- System.out.println("Finish encryption:");
- System.out.println(new String(cipherText,"UTF8"));
-
- System.out.println("\nStart decryption:");
- cipher.init(Cipher.DECRYPT_MODE,key);
- byte[] newPlainText=cipher.doFinal(cipherText);
- System.out.println("Finish decryption:");
-
- System.out.println(new String(newPlainText,"UTF8"));
- }
- }
/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
/**
*˽?¼ÓÃÜ&&±&Ö¤Ï&Ï&&uÃÜÐÔ
*/
public class PrivateExample{
public static void main(String[] args) throws Exception{
byte[] plainText="12345678".getBytes();
//Í‥¹&KeyGeneratorÐγÉÒ&&&key
System.out.println("\nStart generate AES key");
KeyGenerator keyGen=KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key=keyGen.generateKey();
System.out.println("Finish generating AES key");
//&&&ÃÒ&&&˽?¼ÓÃÜÀaCipher&&ECBÊǼÓÃÜ·½Ê½&&PKCS5PaddingÊÇÌ&³&·½·‥
Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("\n"+cipher.getProvider().getInfo());
//ʹÓÃ˽?¼ÓÃÜ
System.out.println("\nStart encryption:");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
System.out.println("\nStart decryption:");
cipher.init(Cipher.DECRYPT_MODE,key);
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
自己稍加修改的例子
- byte[] plainText="12345678".getBytes();
-
-
- System.out.println("\nStart generate AES key");
- KeyGenerator keyGen=KeyGenerator.getInstance("AES");
-
- String pwd = "passord";
- keyGen.init(128, new SecureRandom(pwd.getBytes()));
-
-
-
- SecretKey skey = keyGen.generateKey();
- byte[] raw = skey.getEncoded();
-
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
-
- System.out.println("Finish generating AES key");
-
-
阅读(626) | 评论(1) | 转发(0) |