常用加密解密——对称加密

Posted ITBusTech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用加密解密——对称加密相关的知识,希望对你有一定的参考价值。

本文主要介绍常用的对称加密算法的Java实现

先添加依赖:

 
   
   
 
  1. <dependency>

  2.    <groupId>org.bouncycastle</groupId>

  3.    <artifactId>bcprov-jdk15on</artifactId>

  4.    <version>1.60</version>

  5. </dependency>

  6. <dependency>

  7.    <groupId>org.bouncycastle</groupId>

  8.    <artifactId>bcpkix-jdk15on</artifactId>

  9.    <version>1.60</version>

  10. </dependency>

AES

我在《Java加密之IV》中提到过分组加密的几种方式,常见的工作模式包括,ECB、CBC、PCBC、CFB、OFB、CTR等。

其中ECB是不需要IV(初始化向量)的:

 
   
   
 
  1. import javax.crypto.*;

  2. import javax.crypto.spec.SecretKeySpec;

  3. import java.security.InvalidKeyException;

  4. import java.security.NoSuchAlgorithmException;

  5. /**

  6. * @see javax.crypto.spec.SecretKeySpec

  7. */

  8. public class AES {

  9.    private static final String key_algorithm = "AES";

  10.    private static final String cipher_algorithm = "AES/ECB/PKCS5Padding";

  11.    public static byte[] encrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, IllegalBlockSizeException {

  12.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  13.        /**

  14.         * 对于某些JDK不支持的工作方式,可以考虑 Cipher cipher = Cipher.getInstance(cipher_algorithm, "BC);

  15.         * 其中BC是Bouncy Castle的简称

  16.         */

  17.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  18.        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

  19.        return cipher.doFinal(data);

  20.    }

  21.    public static byte[] decrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

  22.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  23.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  24.        cipher.init(Cipher.DECRYPT_MODE, secretKey);

  25.        return cipher.doFinal(data);

  26.    }

  27. }

单元测试:

 
   
   
 
  1. import cn.dubby.encrypt.encoding.HexUtil;

  2. import cn.dubby.symmetric.encryption.AES;

  3. import cn.dubby.symmetric.encryption.DES;

  4. import org.junit.Test;

  5. import javax.crypto.*;

  6. import java.nio.charset.Charset;

  7. import java.security.InvalidKeyException;

  8. import java.security.NoSuchAlgorithmException;

  9. import java.security.spec.InvalidKeySpecException;

  10. public class AESTest {

  11.    @Test

  12.    public void encryptDecrypt() throws NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, InvalidKeyException {

  13.        String data = "Hello, world.";

  14.        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

  15.        keyGenerator.init(256);

  16.        SecretKey secretKey = keyGenerator.generateKey();

  17.        byte[] keyBytes = secretKey.getEncoded();

  18.        byte[] encryptBytes = AES.encrypt(keyBytes, data.getBytes(Charset.forName("UTF-8")));

  19.        System.out.println(HexUtil.toHex(encryptBytes));

  20.        byte[] decryptBytes = AES.decrypt(keyBytes, encryptBytes);

  21.        System.out.println(new String(decryptBytes, Charset.forName("UTF-8")));

  22.    }

  23. }

而PCBC是需要IV的:

 
   
   
 
  1. import javax.crypto.*;

  2. import javax.crypto.spec.IvParameterSpec;

  3. import javax.crypto.spec.SecretKeySpec;

  4. import java.security.InvalidAlgorithmParameterException;

  5. import java.security.InvalidKeyException;

  6. import java.security.NoSuchAlgorithmException;

  7. /**

  8. * @see SecretKeySpec

  9. */

  10. public class AES_PCBC {

  11.    private static final String key_algorithm = "AES";

  12.    private static final String cipher_algorithm = "AES/PCBC/PKCS5Padding";

  13.    public static byte[] encrypt(byte[] ivBytes, byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, IllegalBlockSizeException, InvalidAlgorithmParameterException {

  14.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  15.        /**

  16.         * 对于某些JDK不支持的工作方式,可以考虑 Cipher cipher = Cipher.getInstance(cipher_algorithm, "BC);

  17.         * 其中BC是Bouncy Castle的简称

  18.         */

  19.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  20.        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));

  21.        return cipher.doFinal(data);

  22.    }

  23.    public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {

  24.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  25.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  26.        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));

  27.        return cipher.doFinal(data);

  28.    }

  29. }

单元测试:

 
   
   
 
  1. import cn.dubby.encrypt.encoding.HexUtil;

  2. import cn.dubby.symmetric.encryption.AES;

  3. import cn.dubby.symmetric.encryption.AES_PCBC;

  4. import org.junit.Test;

  5. import javax.crypto.*;

  6. import java.nio.charset.Charset;

  7. import java.security.InvalidAlgorithmParameterException;

  8. import java.security.InvalidKeyException;

  9. import java.security.NoSuchAlgorithmException;

  10. import java.security.spec.InvalidKeySpecException;

  11. public class AES_PCBCTest {

  12.    @Test

  13.    public void encryptDecrypt() throws NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException {

  14.        /**

  15.         * iv必须是16位

  16.         */

  17.        String data = "Hello, world.", iv = "1234567812345678";

  18.        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

  19.        keyGenerator.init(256);

  20.        SecretKey secretKey = keyGenerator.generateKey();

  21.        byte[] keyBytes = secretKey.getEncoded();

  22.        byte[] encryptBytes = AES_PCBC.encrypt(iv.getBytes(Charset.forName("UTF-8")), keyBytes, data.getBytes(Charset.forName("UTF-8")));

  23.        System.out.println(HexUtil.toHex(encryptBytes));

  24.        byte[] decryptBytes = AES_PCBC.decrypt(iv.getBytes(Charset.forName("UTF-8")), keyBytes, encryptBytes);

  25.        System.out.println(new String(decryptBytes, Charset.forName("UTF-8")));

  26.    }

  27. }

DES

 
   
   
 
  1. import javax.crypto.*;

  2. import javax.crypto.spec.DESKeySpec;

  3. import java.security.InvalidKeyException;

  4. import java.security.NoSuchAlgorithmException;

  5. import java.security.spec.InvalidKeySpecException;

  6. /**

  7. * @see javax.crypto.spec.DESKeySpec

  8. */

  9. public class DES {

  10.    private static final String key_algorithm = "DES";

  11.    private static final String cipher_algorithm = "DES/ECB/PKCS5Padding";

  12.    public static byte[] encrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

  13.        DESKeySpec desKeySpec = new DESKeySpec(keyBytes);

  14.        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key_algorithm);

  15.        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

  16.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  17.        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

  18.        return cipher.doFinal(data);

  19.    }

  20.    public static byte[] decrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

  21.        DESKeySpec desKeySpec = new DESKeySpec(keyBytes);

  22.        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key_algorithm);

  23.        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

  24.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  25.        cipher.init(Cipher.DECRYPT_MODE, secretKey);

  26.        return cipher.doFinal(data);

  27.    }

  28. }

单元测试:

 
   
   
 
  1. import cn.dubby.encrypt.encoding.HexUtil;

  2. import cn.dubby.symmetric.encryption.DES;

  3. import org.junit.Test;

  4. import javax.crypto.*;

  5. import java.nio.charset.Charset;

  6. import java.security.InvalidKeyException;

  7. import java.security.NoSuchAlgorithmException;

  8. import java.security.spec.InvalidKeySpecException;

  9. public class DESTest {

  10.    @Test

  11.    public void encryptDecrypt() throws NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, InvalidKeyException {

  12.        String data = "Hello, world.";

  13.        KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");

  14.        keyGenerator.init(56);

  15.        SecretKey secretKey = keyGenerator.generateKey();

  16.        byte[] keyBytes = secretKey.getEncoded();

  17.        byte[] encryptBytes = DES.encrypt(keyBytes, data.getBytes(Charset.forName("UTF-8")));

  18.        System.out.println(HexUtil.toHex(encryptBytes));

  19.        byte[] decryptBytes = DES.decrypt(keyBytes, encryptBytes);

  20.        System.out.println(new String(decryptBytes, Charset.forName("UTF-8")));

  21.    }

  22. }

DESede

 
   
   
 
  1. import javax.crypto.*;

  2. import javax.crypto.spec.DESedeKeySpec;

  3. import java.security.InvalidKeyException;

  4. import java.security.NoSuchAlgorithmException;

  5. import java.security.spec.InvalidKeySpecException;

  6. /**

  7. * @see javax.crypto.spec.DESedeKeySpec

  8. */

  9. public class DESede {

  10.    private static final String key_algorithm = "DESede";

  11.    private static final String cipher_algorithm = "DESede/ECB/PKCS5Padding";

  12.    public static byte[] encrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

  13.        DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(keyBytes);

  14.        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key_algorithm);

  15.        SecretKey secretKey = keyFactory.generateSecret(deSedeKeySpec);

  16.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  17.        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

  18.        return cipher.doFinal(data);

  19.    }

  20.    public static byte[] decrypt(byte[] keyBytes, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

  21.        DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(keyBytes);

  22.        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key_algorithm);

  23.        SecretKey secretKey = keyFactory.generateSecret(deSedeKeySpec);

  24.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  25.        cipher.init(Cipher.DECRYPT_MODE, secretKey);

  26.        return cipher.doFinal(data);

  27.    }

  28. }

单元测试:

 
   
   
 
  1. package cn.dubby.symmetric.encryption.test;

  2. import cn.dubby.encrypt.encoding.HexUtil;

  3. import cn.dubby.symmetric.encryption.DESede;

  4. import org.junit.Test;

  5. import javax.crypto.*;

  6. import java.nio.charset.Charset;

  7. import java.security.InvalidKeyException;

  8. import java.security.NoSuchAlgorithmException;

  9. import java.security.spec.InvalidKeySpecException;

  10. public class DESedeTest {

  11.    @Test

  12.    public void encryptDecrypt() throws NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, InvalidKeyException {

  13.        String data = "Hello, world.";

  14.        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");

  15.        keyGenerator.init(168);//还可以选112

  16.        SecretKey secretKey = keyGenerator.generateKey();

  17.        byte[] keyBytes = secretKey.getEncoded();

  18.        byte[] encryptBytes = DESede.encrypt(keyBytes, data.getBytes(Charset.forName("UTF-8")));

  19.        System.out.println(HexUtil.toHex(encryptBytes));

  20.        byte[] decryptBytes = DESede.decrypt(keyBytes, encryptBytes);

  21.        System.out.println(new String(decryptBytes, Charset.forName("UTF-8")));

  22.    }

  23. }

IDEA

 
   
   
 
  1. import org.bouncycastle.jce.provider.BouncyCastleProvider;

  2. import javax.crypto.*;

  3. import javax.crypto.spec.SecretKeySpec;

  4. import java.security.InvalidKeyException;

  5. import java.security.NoSuchAlgorithmException;

  6. import java.security.Security;

  7. public class IDEA {

  8.    static {

  9.        Security.addProvider(new BouncyCastleProvider());

  10.    }

  11.    private static final String key_algorithm = "IDEA";

  12.    private static final String cipher_algorithm = "IDEA/ECB/ISO10126Padding";

  13.    public static byte[] encrypt(byte[] keyBytes, byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

  14.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  15.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  16.        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

  17.        return cipher.doFinal(data);

  18.    }

  19.    public static byte[] decrypt(byte[] keyBytes, byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {

  20.        SecretKey secretKey = new SecretKeySpec(keyBytes, key_algorithm);

  21.        Cipher cipher = Cipher.getInstance(cipher_algorithm);

  22.        cipher.init(Cipher.DECRYPT_MODE, secretKey);

  23.        return cipher.doFinal(data);

  24.    }

  25.    /**

  26.     * 生成一个随机的秘钥

  27.     */

  28.    public static byte[] initKey() throws NoSuchAlgorithmException {

  29.        KeyGenerator keyGenerator = KeyGenerator.getInstance(key_algorithm);

  30.        keyGenerator.init(128);

  31.        SecretKey secretKey = keyGenerator.generateKey();

  32.        return secretKey.getEncoded();

  33.    }

  34. }

单元测试:

 
   
   
 
  1. import cn.dubby.encrypt.encoding.HexUtil;

  2. import cn.dubby.symmetric.encryption.IDEA;

  3. import org.junit.Test;

  4. import javax.crypto.BadPaddingException;

  5. import javax.crypto.IllegalBlockSizeException;

  6. import javax.crypto.NoSuchPaddingException;

  7. import java.nio.charset.Charset;

  8. import java.security.InvalidKeyException;

  9. import java.security.NoSuchAlgorithmException;

  10. public class IDEATest {

  11.    @Test

  12.    public void encryptDecrypt() throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException {

  13.        String data = "Hello, world.";

  14.        byte[] keyBytes = IDEA.initKey();

  15.        byte[] encryptBytes = IDEA.encrypt(keyBytes, data.getBytes(Charset.forName("UTF-8")));

  16.        System.out.println(HexUtil.toHex(encryptBytes));

  17.        byte[] decryptBytes = IDEA.decrypt(keyBytes, encryptBytes);

  18.        System.out.println(new String(decryptBytes, Charset.forName("UTF-8")));

  19.    }

  20. }


以上是关于常用加密解密——对称加密的主要内容,如果未能解决你的问题,请参考以下文章

目前常用的加密方式主要有哪两种

常用加密算法之非对称加密算法

常用加密解密——非对称加密

对称加密算法以及使用方法

常用的加密算法--对称加密

常用的加密算法--对称加密