一、引言

对称加密算法,也称为密钥加密算法,是加密和解密使用相同密钥的一类加密算法。在Java中,这些算法常用于数据的安全传输和存储。本文将为您详细解析三种常用对称加密算法的实现原理,并给出具体的Java代码示例。

二、AES (高级加密标准)

AES,全称为Advanced Encryption Standard,是美国联邦政府采用的一种区块加密标准。它采用分组加密的方式,对每个数据块进行独立加密。AES提供了128位、192位和256位三种密钥长度,分别使用128位、192位和256位密钥进行数据加密。 ::: block-1

  1. 选择一个密钥:AES算法需要一个密钥,这个密钥可以是128位、192位或256位长。密钥的长度决定了AES加密的安全性。
  2. 选择一个模式:AES可以与多种模式一起使用,例如ECB(电子密码本)模式、CBC(密码块链)模式、CFB(密码反馈)模式、OFB(输出反馈)模式和CTR(计数器)模式。这些模式定义了如何使用AES算法来加密数据。
  3. 初始化向量(可选):在某些模式中,如CBC和CTR,需要一个初始化向量。初始化向量是随机的,用于增强安全性。
  4. 加密过程
  • 加密器实例化:首先,你需要使用Java的Cipher类创建一个AES加密器实例。例如,要创建一个使用AES/CBC/PKCS5Padding模式的加密器,你可以使用以下代码:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  • 设置密钥和初始化向量:接下来,你需要设置密钥和初始化向量。如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

其中secretKey是你要使用的密钥,ivParameterSpec是一个IvParameterSpec对象,用于指定初始化向量。

  • 加密数据:最后,你可以使用加密器来加密数据。例如:
byte[] encrypted = cipher.doFinal(plainText);

其中plainText是要加密的原始数据,encrypted是加密后的数据。

  1. 解密过程:解密过程与加密过程类似,但方向相反。以下是解密过程的步骤:
  • 解密器实例化:同样,你需要使用Java的Cipher类创建一个AES解密器实例。例如:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  • 设置密钥和初始化向量:解密时也需要设置密钥和初始化向量。与加密相同,如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
  • 解密数据:最后,你可以使用解密器来解密数据。例如:
byte[] decrypted = cipher.doFinal(encrypted);

其中encrypted是要解密的加密数据,decrypted是解密后的原始数据。

::: Java实现示例:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESExample {
    public static String encrypt(String plainText, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] originalBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = cipher.doFinal(originalBytes);
        return new String(decryptedBytes);
    }
}

在实际应用中,你需要确保密钥的安全性,防止它被泄露。此外,你应该使用安全的随机数生成器来生成初始化向量。最后,你应该定期更新密钥,以防止密钥被破解。

三、DES (数据加密标准)

DES,全称为Data Encryption Standard,是最早的国际加密标准。它使用56位密钥和64位明文块进行加密,产生64位密文块。值得注意的是,DES的安全性在现代计算机科学中已经不再被认为足够安全。这是因为现代计算机可以并行处理大量数据,从而在合理的时间内暴力破解DES加密。因此,对于需要高安全性的应用,更推荐使用更安全的加密算法,如AES。 ::: block-1

  1. 密钥生成:DES使用一个64位的密钥来加密和解密数据。但是,实际使用的密钥长度只有56位,因为8位用于奇偶校验。
  2. 初始置换:输入的64位数据块首先经过一个初始置换函数,将数据重新排列。
  3. 16轮迭代:接下来,数据会经过16轮的迭代,每一轮都使用一个特定的函数进行操作。每一轮都涉及到替换(Substitution)、行位移(Permutation)和模2^32乘法(乘法)。
  4. 逆初始置换:经过16轮迭代后,数据会经过一个逆初始置换函数,将数据重新排列回原来的顺序。
  5. 输出:最后,输出的64位数据就是加密后的结果。

解密的过程与加密过程类似,只是每一轮的函数顺序相反。首先进行逆初始置换,然后进行16轮迭代(但每一轮的函数顺序与加密时相反),最后进行初始置换。 ::: Java实现示例:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class DESExample {   
     public static void main(String[] args) throws Exception {        
         String key = "abcdefgh"; // DES密钥必须为8字节长        
         String plaintext = "Hello, World!";
        //加密        
        String encrypted = encrypt(key, plaintext);
        System.out.println("Encrypted: " + encrypted);

        //解密        
        String decrypted = decrypt(key, encrypted);
        System.out.println("Decrypted: " + decrypted);
    }    
    public static String encrypt(String key, String plaintext) throws Exception {        
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKeySpec);
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, securekey);
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }    
    public static String decrypt(String key, String ciphertext) throws Exception {        
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKeySpec);
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, securekey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}

四、3DES (三重数据加密算法)

3DES是对DES的一种扩展,通过使用三个DES加密算法来增加安全性。它使用三个密钥进行三次加密,从而提供更高的安全性。然而,由于计算开销较大,3DES在现代应用中并不常用。 ::: block-1

  1. 密钥生成:3DES使用一个密钥作为输入,生成三个密钥,分别为K1、K2和K3。这三个密钥都用于加密和解密过程。
  2. 加密过程:明文被分为长度为64位的块,然后通过三个密钥进行三次加密。第一次使用K1加密,第二次使用K2解密(实际上是使用了与第一次相反的密钥),第三次使用K3加密。
  3. 解密过程:解密过程与加密过程相反。首先使用K3解密,然后使用K2加密,最后使用K1解密。

具体地,一个64位的块被分为两个32位的子块,每个子块都单独加密。每个密钥都用于一个电子密码本(ECB)模式下的DES加密。因此,每个块都独立地加密和解密。 ::: Java实现示例:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class DESedeExample {    
    public static void main(String[] args) throws Exception {       
        String key = "ac1rm9cpac1rm9cpac1rm9cp"; // 3DES密钥必须为24字节长        
        String plaintext = "Hello, World!";
        //加密        
        String cipherText = encrypt(key, plaintext);
        System.out.println("cipherText: " + cipherText);

        //解密        
        String decryptedText = decrypt(key, cipherText);
        System.out.println("DecryptedText: " + decryptedText);
    }    
    public static String encrypt(String key, String plaintext) throws Exception {        
        DESedeKeySpec des3KeySpec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey securekey = keyFactory.generateSecret(des3KeySpec);
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, securekey);
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }    
    public static String decrypt(String key, String ciphertext) throws Exception {        
        DESedeKeySpec des3KeySpec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey securekey = keyFactory.generateSecret(des3KeySpec);
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, securekey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}

五、总结

本文详细介绍了Java中常用的三种对称加密算法:AES、DES、3DES的实现原理。通过了解这些算法的原理和特点,您可以在实际应用中选择合适的加密算法来保护您的数据安全。同时提供了具体的Java代码示例,帮助您快速实现这些算法的加密和解密操作。