DES、3DES、AES、PBE对称加密算法实现及应用

安全 数据安全 算法
对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。

 [[272601]]

1.对称加密算法概述

对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。

在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。

对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。

不足之处是,交易双方都使用同样钥匙,安全性得不到保证。

在计算机系统中广泛使用的对称加密算法有DES和IDEA等。因为DES近年来屡屡被破解,所以,美国国家标准局倡导的AES即将作为新标准取代DES。

2.对称加密算法-DES

DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。

明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。

引入Bouncy Castle依赖:

<dependency> 
   <groupId>org.bouncycastle</groupId> 
   <artifactId>bcprov-jdk15</artifactId> 
   <version>1.46</version> 
</dependency> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

引入Commons Codec依赖:

<dependency> 
   <groupId>commons-codec</groupId> 
   <artifactId>commons-codec</artifactId> 
   <version>1.10</version> 
</dependency> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

Java代码实现:

import java.security.Key
import java.security.Security; 
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESKeySpec; 
import org.apache.commons.codec.binary.Hex; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
 
public class DES { 
 
  public static final String src = "des test"
 
  public static void main(String[] args) { 
    jdkDES(); 
    bcDES(); 
  } 
 
  // 用jdk实现: 
  public static void jdkDES() { 
    try { 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); 
      keyGenerator.init(56); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] bytesKey = secretKey.getEncoded(); 
 
      // KEY转换 
      DESKeySpec desKeySpec = new DESKeySpec(bytesKey); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); 
      Key convertSecretKey = factory.generateSecret(desKeySpec); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("jdk des encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); 
      result = cipher.doFinal(result); 
      System.out.println("jdk des decrypt:" + new String(result)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
 
  // 用bouncy castle实现: 
  public static void bcDES() { 
    try { 
      Security.addProvider(new BouncyCastleProvider()); 
 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("DES""BC"); 
      keyGenerator.getProvider(); 
      keyGenerator.init(56); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] bytesKey = secretKey.getEncoded(); 
 
      // KEY转换 
      DESKeySpec desKeySpec = new DESKeySpec(bytesKey); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); 
      Key convertSecretKey = factory.generateSecret(desKeySpec); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("bc des encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); 
      result = cipher.doFinal(result); 
      System.out.println("bc des decrypt:" + new String(result)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.

 

应用例子:

 

3.对称加密算法-3DES

密码学中,三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为TDEA,Triple DEA),或称3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

Java代码实现:

import java.security.Key
import java.security.SecureRandom; 
import java.security.Security; 
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESedeKeySpec; 
import org.apache.commons.codec.binary.Hex; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
 
public class DES3 { 
 
  public static final String src = "3des test"
 
  public static void main(String[] args) { 
    jdk3DES(); 
    bc3DES(); 
  } 
 
  // 用jdk实现: 
  public static void jdk3DES() { 
    try { 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); 
      // 必须长度是:112或168 
//            keyGenerator.init(168); 
      keyGenerator.init(new SecureRandom()); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] bytesKey = secretKey.getEncoded(); 
 
      // KEY转换 
      DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede"); 
      Key convertSecretKey = factory.generateSecret(desKeySpec); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("jdk 3des encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); 
      result = cipher.doFinal(result); 
      System.out.println("jdk 3des decrypt:" + new String(result)); 
 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
 
  // 用bouncy castle实现: 
  public static void bc3DES() { 
    try { 
      Security.addProvider(new BouncyCastleProvider()); 
 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede""BC"); 
      keyGenerator.getProvider(); 
      keyGenerator.init(168); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] bytesKey = secretKey.getEncoded(); 
 
      // KEY转换 
      DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede"); 
      Key convertSecretKey = factory.generateSecret(desKeySpec); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("bc 3des encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); 
      result = cipher.doFinal(result); 
      System.out.println("bc 3des decrypt:" + new String(result)); 
 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.

4.对称加密算法-AES

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

该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael为名投稿高级加密标准的甄选流程。(Rijndael的发音近于"Rhine doll")

Java代码实现:

import java.security.Key
import java.security.Security; 
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.Hex; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
 
public class AES { 
 
  public static final String src = "aes test"
 
  public static void main(String[] args) { 
    jdkAES(); 
    bcAES(); 
  } 
 
  // 用jdk实现: 
  public static void jdkAES() { 
    try { 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); 
      keyGenerator.init(128); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] keyBytes = secretKey.getEncoded(); 
 
      // KEY转换 
      Key key = new SecretKeySpec(keyBytes, "AES"); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("jdk aes encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, key); 
      result = cipher.doFinal(result); 
      System.out.println("jdk aes decrypt:" + new String(result)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
 
  // 用bouncy castle实现: 
  public static void bcAES() { 
    try { 
      Security.addProvider(new BouncyCastleProvider()); 
 
      // 生成KEY 
      KeyGenerator keyGenerator = KeyGenerator.getInstance("AES""BC"); 
      keyGenerator.getProvider(); 
      keyGenerator.init(128); 
      // 产生密钥 
      SecretKey secretKey = keyGenerator.generateKey(); 
      // 获取密钥 
      byte[] keyBytes = secretKey.getEncoded(); 
 
      // KEY转换 
      Key key = new SecretKeySpec(keyBytes, "AES"); 
 
      // 加密 
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("bc aes encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, key); 
      result = cipher.doFinal(result); 
      System.out.println("bc aes decrypt:" + new String(result)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.

5.对称加密算法-PBE

PBE算法(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。

PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法。

具体实现如下:

Java代码实现:

import java.security.Key
import java.security.SecureRandom; 
import javax.crypto.Cipher; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.PBEParameterSpec; 
import org.apache.commons.codec.binary.Hex; 
 
public class PBE { 
 
  public static final String src = "pbe test"
 
  public static void main(String[] args) { 
    jdkPBE(); 
  } 
 
  // 用jdk实现: 
  public static void jdkPBE() { 
    try { 
      // 初始化盐 
      SecureRandom random = new SecureRandom(); 
      byte[] salt = random.generateSeed(8); 
 
      // 口令与密钥 
      String password = "timliu"
      PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES"); 
      Key key = factory.generateSecret(pbeKeySpec); 
 
      // 加密 
      PBEParameterSpec pbeParameterSpac = new PBEParameterSpec(salt, 100); 
      Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); 
      cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpac); 
      byte[] result = cipher.doFinal(src.getBytes()); 
      System.out.println("jdk pbe encrypt:" + Hex.encodeHexString(result)); 
 
      // 解密 
      cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpac); 
      result = cipher.doFinal(result); 
      System.out.println("jdk pbe decrypt:" + new String(result)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

应用举例:

 

责任编辑:武晓燕 来源: 薛勤的博客
相关推荐

2011-06-22 11:04:25

加密ARM3DES

2011-06-22 14:00:22

2023-07-30 17:44:24

CryptoJS加密字符串

2010-09-08 16:01:33

加密算法协议

2023-08-01 07:24:05

2009-08-13 18:12:11

C#数据加密

2009-08-04 11:08:33

ASP.NET数据加密

2012-05-21 23:53:21

Java.NETDES加密

2023-08-02 07:27:53

2024-12-31 08:00:00

SpringBoot开发加密

2010-07-28 10:09:01

2011-08-18 12:12:29

2023-12-13 12:27:46

2009-09-04 16:45:44

C# DES算法加密解

2018-07-10 10:29:27

2015-03-26 11:25:10

对称加密加密压缩加密解密解压

2020-12-11 06:41:15

AES加密

2022-01-11 12:12:10

加密漏洞攻击

2009-09-04 17:20:23

C# DES加密解密

2024-08-26 08:34:47

AES加密算法
点赞
收藏

51CTO技术栈公众号