Chinaunix首页 | 论坛 | 博客
  • 博客访问: 516916
  • 博文数量: 135
  • 博客积分: 3568
  • 博客等级: 中校
  • 技术积分: 1942
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-19 17:52
文章分类

全部博文(135)

文章存档

2012年(29)

2011年(41)

2010年(26)

2009年(12)

2008年(9)

2007年(12)

2006年(6)

分类: Java

2010-06-22 14:57:06

"ECB" is the default Cipher Mode and "PKCS5Padding" the default padding

AESUtil.java

package test.crypto;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {

    public static final String ALGORITHM = "AES";

    /** 128, 192, 256 */
    // when keysize != 128

    // Download Java(TM) Cryptography Extension (JCE) Unlimited Strength

    // Jurisdiction Policy Files

    // file name : jce_policy-6.zip

    private int keySize = 128;

    private String transformation = null;

    private static AESUtil instance = null;

    private AESUtil(int keySize, String transformation) {
        super();
        this.keySize = keySize;
        this.transformation = transformation;
    }

    public synchronized static AESUtil getInstance() {
        if (instance == null) {
            instance = new AESUtil(128, "AES/CBC/PKCS5Padding");
        }
        return instance;
    }

    public byte[] encode(byte[] key, byte[] data) throws InvalidKeyException,
            InvalidAlgorithmParameterException, IllegalBlockSizeException,
            BadPaddingException, NoSuchProviderException {

        SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
        IvParameterSpec iv = new IvParameterSpec(new byte[16]);

        try {
            Cipher cipher = Cipher.getInstance(transformation);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            return cipher.doFinal(data);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (NoSuchPaddingException e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] decode(byte[] key, byte[] data) throws InvalidKeyException,
            InvalidAlgorithmParameterException, IllegalBlockSizeException,
            BadPaddingException {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(new byte[16]);
            Cipher cipher = Cipher.getInstance(transformation);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            return cipher.doFinal(data);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (NoSuchPaddingException e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] generateRandomKey() throws RuntimeException {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
            kgen.init(keySize, new SecureRandom());
            SecretKey skey = kgen.generateKey();
            return skey.getEncoded();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] generateKey(byte[] seed) throws RuntimeException {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
            kgen.init(keySize, new SecureRandom(seed));
            SecretKey skey = kgen.generateKey();
            return skey.getEncoded();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws Exception {
        AESUtil aesUtil = AESUtil.getInstance();

        byte[] key = aesUtil.generateRandomKey();
        System.out.println("key length : " + key.length + " bytes ("
                + (key.length * 8) + " bits)");
        System.out.println("key data : " + Arrays.toString(key));

        String dataStr = "Hello world!";
        byte[] data = dataStr.getBytes();
        System.out.println("plain text : " + dataStr);
        System.out.println(" : " + Arrays.toString(data));

        byte[] encData = aesUtil.encode(key, data);
        System.out.println("encrypted data : " + Arrays.toString(encData));

        byte[] decData = aesUtil.decode(key, encData);
        System.out.println("decrypted data : " + Arrays.toString(decData));
        System.out.println("decrypted data (text) : " + new String(decData));
    }
}


Output

key length : 16 bytes (128 bits)
key data : [100, 55, 123, -122, -74, 0, 110, 81, 1, 37, -26, 104, 56, -84, -82, -80]
plain text : Hello
           : [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]
encrypted data : [-7, -34, 71, -45, -96, 106, -8, 44, -40, 25, -46, 14, -65, -109, -12, -46]
decrypted data : [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]
decrypted data (text) : Hello


=======================
Standard Algorithm Name Documentation
《》

用户输入的密码不见得都是固定128比特、256比特。如何将用户的输入的密码映射为唯一(碰撞机率低)的AES密码?且看下面代码;

GenAESKey.java

点击(此处)折叠或打开

  1. import java.security.MessageDigest;
  2. import java.util.Arrays;

  3. import javax.crypto.SecretKey;
  4. import javax.crypto.spec.SecretKeySpec;

  5. public class GenAESKey {

  6.     public static void main(String[] args) throws Exception {
  7.         SecretKey key = null;
  8.         key = getSecretKeyBaseOnUserPassword("123", 128);
  9.         System.out.println(Arrays.toString(key.getEncoded()));
  10.         System.out.println(Arrays.toString(key.getEncoded()));
  11.     }

  12.     private static SecretKey getSecretKeyBaseOnUserPassword(
  13.             String userPassword, int keySize) {
  14.         try {
  15.             // AES 的密码长度有 128, 192, 256 三种,故在选择满足其最大长度的摘要算法。
  16.             // 注意:如果要使用 256 位的AES,需要下载 JCE
  17.             MessageDigest digester = MessageDigest.getInstance("SHA-256");

  18.             byte[] digest = digester.digest(userPassword.getBytes("UTF-8"));
  19.             byte[] key = new byte[keySize / 8];
  20.             System.arraycopy(digest, 0, key, 0, keySize / 8);

  21.             return new SecretKeySpec(key, "AES");

  22.         } catch (Exception e) {
  23.             throw new RuntimeException(e);
  24.         }
  25.     }
  26. }

运行结果:

点击(此处)折叠或打开

  1. [-90, 101, -92, 89, 32, 66, 47, -99, 65, 126, 72, 103, -17, -36, 79, -72]
  2. [-90, 101, -92, 89, 32, 66, 47, -99, 65, 126, 72, 103, -17, -36, 79, -72]







阅读(975) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~