AES对称加密例子

原文地址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.*;

   /**
   * 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;


    // 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) {


    // 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







别人的例子



/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;

/**
*&Euml;&frac12;?&frac14;&Oacute;&Atilde;&Uuml;&amp;&amp;±&amp;&Ouml;¤&Iuml;&amp;&Iuml;&amp;&amp;u&Atilde;&Uuml;&ETH;&Ocirc;
*/
public class PrivateExample{
    public static void main(String[] args) throws Exception{
    
    byte[] plainText="12345678".getBytes();

    //&Iacute;‥&sup1;&amp;KeyGenerator&ETH;&Icirc;&sup3;&Eacute;&Ograve;&amp;&amp;&amp;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");

    //&amp;&amp;&amp;&Atilde;&Ograve;&amp;&amp;&amp;&Euml;&frac12;?&frac14;&Oacute;&Atilde;&Uuml;&Agrave;aCipher&amp;&amp;ECB&Ecirc;&Ccedil;&frac14;&Oacute;&Atilde;&Uuml;·&frac12;&Ecirc;&frac12;&amp;&amp;PKCS5Padding&Ecirc;&Ccedil;&Igrave;&amp;&sup3;&amp;·&frac12;·‥
    Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
    System.out.println("\n"+cipher.getProvider().getInfo());

    //&Ecirc;&sup1;&Oacute;&Atilde;&Euml;&frac12;?&frac14;&Oacute;&Atilde;&Uuml;
    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();

	    //&Iacute;‥&sup1;&amp;KeyGenerator&ETH;&Icirc;&sup3;&Eacute;&Ograve;&amp;&amp;&amp;key
	    System.out.println("\nStart generate AES key");
	    KeyGenerator keyGen=KeyGenerator.getInstance("AES");
	    
	    String pwd = "passord";
	    keyGen.init(128, new SecureRandom(pwd.getBytes()));
	    //keyGen.init(128);
	    
	    //Key key=keyGen.generateKey();
        SecretKey skey = keyGen.generateKey();
        byte[] raw = skey.getEncoded();

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

	    System.out.println("Finish generating AES key");

	    //&amp;&amp;&amp;&Atilde;&Ograve;&amp;&amp;&amp;&Euml;&frac12;?&frac14;&Oacute;&Atilde;&Uuml;&Agrave;aCipher&amp;&amp;ECB&Ecirc;&Ccedil;&frac14;&Oacute;&Atilde;&Uuml;E&frac12;&Ecirc;&frac12;&amp;&amp;PKCS5Padding&Ecirc;&Ccedil;&Igrave;&amp;&sup3;&amp;E&frac12;E‥
	    Cipher cipher=Cipher.getInstance("AES");
	    System.out.println("\n"+cipher.getProvider().getInfo());

	    //&Ecirc;&sup1;&Oacute;&Atilde;&Euml;&frac12;?&frac14;&Oacute;&Atilde;&Uuml;
	    System.out.println("\nStart encryption:");
	    cipher.init(Cipher.ENCRYPT_MODE,skeySpec);
	    
	    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,skeySpec);
	    byte[] newPlainText=cipher.doFinal(cipherText);
	    System.out.println("Finish decryption:");

	    System.out.println(new String(newPlainText,"UTF8"));
	}




你可能感兴趣的:(.net,socket,Security,J#,sun)