加密解密(三)——对称加密算法

一.什么是对称加密

  对称加密算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。数据发信方将明文和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通信联系。与非对称加密相比,要求双方获取相同的密钥是对称密钥加密的主要缺点之一。
  由于对称加密的速度比公钥加密快很多,所以在很多场合都需要对称加密。
  下图是对称加密算法的描述:

二.常见的对称加密算法

  常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6等。
  对于:“Illegal key size or default parameters”异常,是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题。
  Java 7 无政策限制文件: java官方下载。将UnlimitedJCEPolicyJDK7.zip 解压后将local_policy.jar、US_export_policy.jar复制(覆盖原先jar)%Java_Home%/jre/lib/security目录下。

1.DES

  数据加密标准(Data Encryption Standard)是一种对称密钥加密块密码算法。
  DES现在已经不是一种安全的加密方法,主要因为它使用的56位密钥过短,为了提供实用所需的安全性,可以使用DES的派生算法3DES来进行加密。在2001年,DES作为一个标准已经被高级加密标准(AES)所取代。
  DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

(1).JDK的实现
package demo.des;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

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.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.junit.Test;

import sun.misc.BASE64Encoder;

public class Demo01_DES_JDK {

    private String message = "This is message";

    private final String ALGORITHM = "DES";  

    @Test
    public void testJDK() throws Exception {
        byte[] keyByte = initKey();
        SecretKey key = toKey(keyByte);
        byte[] encryptResult = encrypt(key);
        System.out.println("加密后的字节数组经Base64加密后为:" + new BASE64Encoder().encode(encryptResult));
        byte[] decryptResult = decrypt(key,encryptResult);
        System.out.println("解密后原始数据为:"+new String(decryptResult));
    }

    /**
     * 生成密钥
     * 
     * @return
     * @throws NoSuchAlgorithmException
     *             没有指定算法的实现
     */
    private byte[] initKey() throws NoSuchAlgorithmException {
        // 获取密钥生成器
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        System.out.println("获取密钥生成器提供者为:" + generator.getProvider());
        // 设置密钥长度,DES必须为56位。new SecureRandom()为构造一个实现默认(DES即为56位)随机数算法的安全随机数生成器
        generator.init(new SecureRandom());
        SecretKey secretKey = generator.generateKey();
        System.out.println("secretKey的实现类为:" + secretKey.getClass());// class com.sun.crypto.provider.DESKey
        byte[] key = secretKey.getEncoded();
        String encode = new BASE64Encoder().encode(key);
        System.out.println("密钥经Base64加密后为:" + encode);
        return key;
    }

    /**
     * 将密钥生成器生成的KEY转换为DES的KEY
     * 
     * @param key
     * @return
     * @throws InvalidKeyException
     *             给定的密钥不合要求
     * @throws NoSuchAlgorithmException
     *             没有指定算法的实现
     * @throws InvalidKeySpecException
     *             给定的密钥规范不适用于该秘密密钥工厂产生密钥
     */
    private SecretKey toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
        DESKeySpec desKeySpec = new DESKeySpec(key);
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey desKey = factory.generateSecret(desKeySpec);
         // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码  
        // SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return desKey;
    }
    /**
     * 加密
     * @param key 密钥对象
     * @return 加密后的byte数组
     * @throws NoSuchAlgorithmException
     *             没有指定算法的实现
     * @throws NoSuchPaddingException
     *             如果转换包含不可用的填充方案
     * @throws InvalidKeyException
     *             给定的密钥错误,不能初始化
     * @throws IllegalBlockSizeException
     *             如果该密码是块密码,则不会请求填充(仅在加密模式下),并且由该密码处理的数据的总输入长度不是块大小的倍数;
     *             或者如果该加密算法不能处理提供的输入数据。
     * @throws BadPaddingException
     *             如果该密码处于解密模式,并且已经请求了(不)填充,但是解密的数据不受适当的填充字节的限制
     */
    private byte[] encrypt(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }

    /**
     * 解密(异常信息见encrypt方法)
     * 
     * @param key
     *            密钥对象
     * @param source
     *            密文
     * @return 解密后的byte数组
     */
    private byte[] decrypt(SecretKey key,byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
    IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(source);
    }
}

  运行结果:

获取密钥生成器提供者为:SunJCE version 1.7
secretKey的实现类为:class com.sun.crypto.provider.DESKey
密钥经Base64加密后为:wphw+D5Aj+w=
加密后的字节数组经Base64加密后为:YClAioHE1Dn/Ge69PZMxVQ==
解密后原始数据为:This is message
(2).BouncyCastle的实现

  总体跟JDK相似,只需要在初始化密钥时添加BouncyCastle的Provider,然后在生成密钥时指定生成器提供者。

package demo.des;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;

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.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;

import sun.misc.BASE64Encoder;

public class Demo02_DES_BouncyCastle {

    private String message = "This is message";

    private final String ALGORITHM = "DES";

    @Test
    public void testBouncyCastle() throws Exception {
        byte[] keyByte = initKey();
        SecretKey key = toKey(keyByte);
        byte[] encryptResult = encrypt(key);
        System.out.println("加密后的字节数组经Base64加密后为:" + new BASE64Encoder().encode(encryptResult));
        byte[] decryptResult = decrypt(key, encryptResult);
        System.out.println("解密后原始数据为:" + new String(decryptResult));
    }

    private byte[] initKey() throws NoSuchAlgorithmException, NoSuchProviderException {
        // 通过调用API添加第三方(BouncyCastle)提供者
        Security.addProvider(new BouncyCastleProvider());
        // 参数一:指定加密算法,参数二:自动生成器提供者(BC表示BouncyCastle)
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM, "BC");
        System.out.println("获取密钥生成器提供者为:" + generator.getProvider());
        // 设置密钥长度,DES必须为56位。new SecureRandom()为构造一个实现默认随机数算法的安全随机数生成器
        generator.init(new SecureRandom());
        SecretKey secretKey = generator.generateKey();
        System.out.println("secretKey的实现类为:" + secretKey.getClass());//class javax.crypto.spec.SecretKeySpec
        byte[] key = secretKey.getEncoded();
        String encode = new BASE64Encoder().encode(key);
        System.out.println("密钥经Base64加密后为:" + encode);
        return key;
    }

    private SecretKey toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
        DESKeySpec desKeySpec = new DESKeySpec(key);
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey desKey = factory.generateSecret(desKeySpec);
        // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码  
        // SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return desKey;
    }

    private byte[] encrypt(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }

    private byte[] decrypt(SecretKey key, byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(source);
    }
}

  运行结果:

获取密钥生成器提供者为:BC version 1.58
secretKey的实现类为:class javax.crypto.spec.SecretKeySpec
密钥经Base64加密后为:KhVYL7pJSho=
加密后的字节数组转为十六进制后结果为:hDXpInX222ksVA5XMx0lCQ==
解密后原始数据为:This is message

2.3DES

  三重数据加密算法(Triple Data Encryption Algorithm),或称3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
  代码上与DES区别在于密钥转换器(toKey()方法中)使用的是DESedeKeySpec。

(1).JDK的实现
package demo.tripleDes;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

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.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.junit.Test;

import sun.misc.BASE64Encoder;

public class Demo01_TripleDES_JDK {
    private String message = "This is message";

    private final String ALGORITHM = "DESede";

    @Test
    public void testJDK() throws Exception {
        byte[] keyByte = initKey();
        SecretKey key = toKey(keyByte);
        byte[] encryptResult = encrypt(key);
        System.out.println("加密后的字节数组经Base64加密后为:" + new BASE64Encoder().encode(encryptResult));
        byte[] decryptResult = decrypt(key,encryptResult);
        System.out.println("解密后原始数据为:"+new String(decryptResult));
    }

    private byte[] initKey() throws NoSuchAlgorithmException {
        // 获取密钥生成器
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        System.out.println("获取密钥生成器提供者为:" + generator.getProvider());
        // 设置密钥长度,3DES必须为112 或 168 位。new SecureRandom()为构造一个实现默认随机数算法的安全随机数生成器
        generator.init(new SecureRandom());
        SecretKey secretKey = generator.generateKey();
        System.out.println("secretKey的实现类为:" + secretKey.getClass());//class com.sun.crypto.provider.DESedeKey
        byte[] key = secretKey.getEncoded();
        String encode = new BASE64Encoder().encode(key);
        System.out.println("密钥经Base64加密后为:" + encode);
        return key;
    }

    private SecretKey toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
        DESedeKeySpec desedeKeySpec = new DESedeKeySpec(key);
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey desKey = factory.generateSecret(desedeKeySpec);
        // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换三行代码
        // SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return desKey;
    }

    private byte[] encrypt(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }

    private byte[] decrypt(SecretKey key,byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
    IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(source);
    }
}

  运行结果:

获取密钥生成器提供者为:SunJCE version 1.7
secretKey的实现类为:class com.sun.crypto.provider.DESedeKey
密钥经Base64加密后为:aEyGhSzOqFS2RcGt/VQNeuB6hVez3Ozg
加密后的字节数组经Base64加密后为:1Vn1Ue+PLoxVpZafeDYRBQ==
解密后原始数据为:This is message
(2).BouncyCastle的实现

  3DES的BouncyCastlequ实现与JDK的实现区别参考DES的BouncyCastle与JDK的区别。只需要完成以下三步(由于代码重复就不贴上代码了):
  ①将初始化密钥的提供者换成BouncyCastle的Provider
  ②将密钥的生成算法换成3DES的算法(DESede)
  ③密钥的转换方式换成DESedeKeySpec

3.AES

  高级加密标准(Advanced Encryption Standard),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
  相对与DES,AES的安全性更加高;而相对于3DES,AES的效率更加高。

(2).JDK的实现
package demo.aes;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

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.SecretKeySpec;

import org.junit.Test;

import sun.misc.BASE64Encoder;

public class Demo01_AES_JDK {
    private String message = "This is message";

    private final String ALGORITHM = "AES";

    @Test
    public void testJDK() throws Exception {
        byte[] keyByte = initKey();
        SecretKey key = toKey(keyByte);
        byte[] encryptResult = encrypt(key);
        System.out.println("加密后的字节数组经Base64加密后为:" + new BASE64Encoder().encode(encryptResult));
        byte[] decryptResult = decrypt(key,encryptResult);
        System.out.println("解密后原始数据为:"+new String(decryptResult));
    }

    private byte[] initKey() throws NoSuchAlgorithmException {
        // 获取密钥生成器
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        System.out.println("获取密钥生成器提供者为:" + generator.getProvider());
        // 设置密钥长度,AES必须为128,192或256位。new SecureRandom()为构造一个实现默认(AES即为128位)随机数算法的安全随机数生成器
        // 192和256位可能不可用,解决方案参考(二.常见的对称加密算法)
        generator.init(new SecureRandom());
        SecretKey secretKey = generator.generateKey();
        System.out.println("secretKey的实现类为:" + secretKey.getClass());//class com.sun.crypto.provider.DESKey
        byte[] key = secretKey.getEncoded();
        String encode = new BASE64Encoder().encode(key);
        System.out.println("密钥经Base64加密后为:" + encode);
        return key;
    }

    private SecretKey toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
//      DESKeySpec desKeySpec = new DESKeySpec(key);
//      SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
//      SecretKey desKey = factory.generateSecret(desKeySpec);
        // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码  
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return secretKey;
    }

    private byte[] encrypt(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }

    private byte[] decrypt(SecretKey key,byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
    IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(source);
    }
}

  运行结果:

获取密钥生成器提供者为:SunJCE version 1.7
secretKey的实现类为:class javax.crypto.spec.SecretKeySpec
密钥经Base64加密后为:g80Lcv05958I90j2nc8TOw==
加密后的字节数组经Base64加密后为:ZWT2aMMMAhIvI11hhkUMew==
解密后原始数据为:This is message
(2).BouncyCastle的实现
package demo.aes;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;

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.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;

import sun.misc.BASE64Encoder;

public class Demo02_AES_BouncyCastle {
    private String message = "This is message";

    private final String ALGORITHM = "AES";

    @Test
    public void testBouncyCastle() throws Exception {
        byte[] keyByte = initKey();
        SecretKey key = toKey(keyByte);
        byte[] encryptResult = encrypt(key);
        System.out.println("加密后的字节数组经Base64加密后为:" + new BASE64Encoder().encode(encryptResult));
        byte[] decryptResult = decrypt(key,encryptResult);
        System.out.println("解密后原始数据为:"+new String(decryptResult));
    }

    private byte[] initKey() throws NoSuchAlgorithmException, NoSuchProviderException {
        // 通过调用API添加第三方(BouncyCastle)提供者
        Security.addProvider(new BouncyCastleProvider());
        // 获取密钥生成器
        KeyGenerator generator = KeyGenerator.getInstance("AES", "BC");
        System.out.println("获取密钥生成器提供者为:" + generator.getProvider());
        // 设置密钥长度,AES必须为128,192或256位。new SecureRandom()为构造一个实现默认(AES即为128位)随机数算法的安全随机数生成器
        // 192和256位可能不可用,[解决方案](#IllegalKeySize)
        generator.init(new SecureRandom());
        SecretKey secretKey = generator.generateKey();
        System.out.println("secretKey的实现类为:" + secretKey.getClass());//class com.sun.crypto.provider.DESKey
        byte[] key = secretKey.getEncoded();
        String encode = new BASE64Encoder().encode(key);
        System.out.println("密钥经Base64加密后为:" + encode);
        return key;
    }

    private SecretKey toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
        // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码  
        SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
        return secretKey;
    }

    private byte[] encrypt(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }

    private byte[] decrypt(SecretKey key,byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
    IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(source);
    }
}

4.PBE

  基于口令加密算法(Password Base Encryption)是一种基于口令的加密算法。特点在于口令由用户自己掌握,采用随机数(我们这里叫做“盐”)杂凑多重加密等方法保证数据的安全性。
  PBE算法没有密钥的概念,把口令当做密钥了。因为密钥长短影响算法安全性,还不方便记忆,这里我们直接换成我们自己常用的口令就大大不同了,便于我们的记忆。但是单纯的口令很容易被字典法给穷举出来,所以我们这里给口令加了点“盐”,这个盐和口令组合,想破解就难了。同时我们将盐和口令合并后用消息摘要算法进行迭代很多次来构建密钥初始化向量的基本材料,使破译更加难了。
  PBE算法没构建新的加密算法,就是用了我们常用的对称加密算法,例如AES,DES等算法。

(1).JDK的实现
package demo.pbe;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.junit.Test;

public class Demo01_PBE {
     /** 
     * 支持以下任意一种算法 
     * PBEWithMD5AndDES  
     * PBEWithMD5AndTripleDES  
     * PBEWithSHA1AndDESede 
     * PBEWithSHA1AndRC2_40 
     */  
    public final String ALGORITHM = "PBEWITHMD5andDES";

    public int iterationNum = 100;

    @Test
    public void testJDK() throws Exception {
        //初始化盐
        byte[] salt = initSalt();
        //密钥转换  
        Key key = getKey("password");
        byte[] encrypt = encrypt(message.getBytes(), key, salt, iterationNum);
        System.out.println("加密后的字节数组经Base64加密后:" + Base64.encodeBase64String(encrypt));     
        byte[] decrypt = decrypt(encrypt, key, salt, iterationNum);
        System.out.println("解密后原始数据为:" + new String(decrypt));
    }

    private String message = "This is message";

    /**
     * 盐初始化 
     * 盐长度必须为8字节 
     * @return byte[] 8字节的盐
     * @throws Exception
     */
    public  byte[] initSalt() throws Exception{  
        //实例化安全随机数  
        SecureRandom random=new SecureRandom(); 
        //产出盐 ,参数表示长度
        return random.generateSeed(8);  
    } 
    /**
     * 密钥转换  
     * @param password
     * @return Key 密钥
     * @throws Exception
     */
    public Key getKey(String password) throws Exception{
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey key = factory.generateSecret(pbeKeySpec);
        return key;
    }

    /**
     * 加密 
     * @param data 待加密数据 
     * @param key 密钥 
     * @param salt 盐
     * @param iteration 迭代次数 
     * @return byte[] 加密数据 
     * @throws Exception
     */
    public byte[] encrypt(byte[] data, Key key,byte[] salt,int iteration) throws Exception{  
        //实例化PBE参数材料  
        PBEParameterSpec paramSpec=new PBEParameterSpec(salt,iteration);
        //实例化  
        Cipher cipher=Cipher.getInstance(ALGORITHM);
        //初始化  
        cipher.init(Cipher.ENCRYPT_MODE, key,paramSpec);  
        //执行操作  
        return cipher.doFinal(data);  
    }  

    /**
     * 加密 
     * @param data 待解密数据 
     * @param key 密钥 
     * @param salt 盐
     * @param iteration 迭代次数 
     * @return byte[] 原始数据
     * @throws Exception
     */
    public byte[] decrypt(byte[] data, Key key,byte[] salt,int iteration) throws Exception{  
        //实例化PBE参数材料  
        PBEParameterSpec paramSpec=new PBEParameterSpec(salt,iteration);
        //实例化  
        Cipher cipher=Cipher.getInstance(ALGORITHM);
        //初始化  
        cipher.init(Cipher.DECRYPT_MODE, key,paramSpec);  
        //执行操作  
        return cipher.doFinal(data);  
    }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值