Cipher-Java中的加密

  • Cipher 是 Java 加密框架的一部分,提供了加密和解密操作的核心功能。
  • Cipher.getInstance(String transformation)
    • 用来获取一个加密算法实例。
    • 参数 transformation 指定了加密算法的详细配置。
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

这段代码的作用是初始化一个加密/解密工具,使用 AES 算法结合 CBC 模式和 PKCS5Padding 填充方式。

AES/CBC/PKCS5Padding 是一个 transformation,由三部分组成:

(1) AES
  • 代表 AES(Advanced Encryption Standard,高级加密标准)
  • 一种对称加密算法,广泛应用于安全通信。
  • 数据块长度固定为 128 位(16 字节)
(2) CBC
  • 代表 Cipher Block Chaining(密码块链接模式)
  • 特点
    • 每个加密块与前一个加密块的结果相关联。
    • 第一个块需要一个随机的 初始化向量(IV)
  • 优点
    • 提高安全性,同样的明文输入生成的密文不同。
  • 注意事项
    • IV 必须是随机生成且长度为 16 字节。
    • IV 通常需要与密文一起存储或传输,供解密时使用。
(3) PKCS5Padding
  • 代表 填充方式
  • 数据块加密需要满足长度为算法要求的整数倍(AES 为 16 字节),如果数据不足,需要填充。
  • PKCS5Padding 的填充规则:
    • 在明文后填充一定数量的字节,填充值等于填充的字节数。
    • 例如:明文长度为 13 字节,缺 3 字节,则填充 03 03 03

1. 常见的加密算法

算法描述
AES高级加密标准,块大小固定为 128 位,密钥长度为 128、192 或 256 位。
DES数据加密标准,块大小为 64 位,但已过时,不推荐使用。
3DES三重 DES,比 DES 更安全,但速度较慢,也逐渐被淘汰。
RSA非对称加密算法,用于加密小数据块或交换密钥。
ChaCha20高性能流加密算法,适合现代系统。

2. 常见的加密模式

模式描述
ECB电子密码本模式(Electronic Codebook),简单但不安全,相同明文块会生成相同密文块,不推荐。
CBC密码块链接模式(Cipher Block Chaining),需要初始化向量(IV),安全性高,推荐用于文件加密。
CFB密码反馈模式(Cipher Feedback),将密文反馈给加密过程,可用于流加密。
OFB输出反馈模式(Output Feedback),类似于 CFB,但不会引入传输错误。
CTR计数器模式(Counter),将计数器值与密钥一起加密生成密文,可并行处理,适合高性能场景。
GCMGalois/Counter 模式,提供认证的加密(AEAD),适合网络传输和安全通信。

3. 常见的填充方式

填充方式描述
PKCS5Padding常用于块加密,适用于块大小为 8 字节(如 DES)或 16 字节(如 AES)的加密算法。
PKCS7Padding类似于 PKCS5Padding,但适用于任意块大小。
NoPadding不进行填充,要求输入数据长度刚好是块大小的整数倍。
ISO10126Padding填充随机数据,最后一个字节表示填充字节数。
ZeroPadding0x00 填充,不推荐用于敏感数据(容易引发歧义)。

4. 示例组合

根据加密需求,可以选择不同的组合:

(1) AES/GCM/NoPadding
  • 用途:认证加密(AEAD,Authenticated Encryption with Associated Data)。
  • 特点:同时提供加密和数据完整性验证。
  • 注意:使用 GCM 时通常不需要额外的填充方式。
(2) AES/CTR/NoPadding
  • 用途:适合流加密或需要高并发的场景(如实时音视频传输)。
  • 特点:将块加密转化为流加密,支持并行处理。
(3) AES/CFB/PKCS5Padding
  • 用途:加密任意长度的数据。
  • 特点:不需要填充数据块,但引入密文依赖。
(4) RSA/ECB/PKCS1Padding
  • 用途:非对称加密,常用于密钥交换或数字签名。
  • 特点:RSA 本质是块加密,ECB 模式足够安全(因为每块独立加密)。

5. 实际使用中的注意事项

  1. 选择加密模式

    • 如果数据长度较短且安全性要求高,优先使用 GCM
    • 如果需要流加密,使用 CTRCFB
    • 避免使用 ECB,因为它容易被攻击。
  2. 填充选择

    • 推荐 PKCS5PaddingPKCS7Padding,它们是最常见的填充方式。
    • 如果输入数据已经对齐块大小,可以使用 NoPadding
  3. 随机性和安全性

    • 使用安全的随机数生成器(如 SecureRandom)生成密钥和 IV。
    • 确保密钥和 IV 不被硬编码或暴露。
  4. 兼容性考虑

    • 确保发送端和接收端使用相同的加密配置(算法、模式、填充方式等)。

下面举例:

1. AES/CBC/PKCS5Padding

用途:安全文件加密,推荐用于通用加密场景。
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class AESCBCExample {
    public static void main(String[] args) throws Exception {
        // 生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // AES-128
        SecretKey secretKey = keyGen.generateKey();

        // 生成初始化向量 (IV)
        byte[] iv = new byte[16];
        new java.security.SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // 原文
        String plainText = "Hello, AES CBC Mode!";

        // 加密
        Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes());
        System.out.println("加密后的内容: " + javax.xml.bind.DatatypeConverter.printHexBinary(cipherText));

        // 解密
        Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedText = decryptCipher.doFinal(cipherText);
        System.out.println("解密后的内容: " + new String(decryptedText));
    }
}

2. AES/CTR/NoPadding

用途:适合实时音视频流加密,支持任意长度数据。
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class AESCTRExample {
    public static void main(String[] args) throws Exception {
        // 生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();

        // 生成初始化向量 (IV)
        byte[] iv = new byte[16];
        new java.security.SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // 原文
        String plainText = "Hello, AES CTR Mode!";

        // 加密
        Cipher encryptCipher = Cipher.getInstance("AES/CTR/NoPadding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes());
        System.out.println("加密后的内容: " + javax.xml.bind.DatatypeConverter.printHexBinary(cipherText));

        // 解密
        Cipher decryptCipher = Cipher.getInstance("AES/CTR/NoPadding");
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedText = decryptCipher.doFinal(cipherText);
        System.out.println("解密后的内容: " + new String(decryptedText));
    }
}

3. AES/GCM/NoPadding

用途:适合网络通信,提供加密和数据完整性认证。
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;

public class AESGCMExample {
    public static void main(String[] args) throws Exception {
        // 生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();

        // 生成初始化向量 (IV)
        byte[] iv = new byte[12]; // GCM 的 IV 通常为 12 字节
        new java.security.SecureRandom().nextBytes(iv);

        // 原文
        String plainText = "Hello, AES GCM Mode!";

        // 加密
        Cipher encryptCipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv); // 认证标签位数 128 位
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmSpec);
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes());
        System.out.println("加密后的内容: " + javax.xml.bind.DatatypeConverter.printHexBinary(cipherText));

        // 解密
        Cipher decryptCipher = Cipher.getInstance("AES/GCM/NoPadding");
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, gcmSpec);
        byte[] decryptedText = decryptCipher.doFinal(cipherText);
        System.out.println("解密后的内容: " + new String(decryptedText));
    }
}

4. RSA/ECB/PKCS1Padding

用途:常用于加密小数据块(如密钥)或数字签名。
import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;

public class RSAExample {
    public static void main(String[] args) throws Exception {
        // 生成 RSA 密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048); // 密钥长度 2048 位
        KeyPair keyPair = keyGen.generateKeyPair();

        // 原文
        String plainText = "Hello, RSA ECB Mode!";

        // 加密
        Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes());
        System.out.println("加密后的内容: " + javax.xml.bind.DatatypeConverter.printHexBinary(cipherText));

        // 解密
        Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
        byte[] decryptedText = decryptCipher.doFinal(cipherText);
        System.out.println("解密后的内容: " + new String(decryptedText));
    }
}

5. AES/CFB/PKCS5Padding

用途:加密任意长度数据,适用于需要部分加密的流式场景。
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class AESCFBExample {
    public static void main(String[] args) throws Exception {
        // 生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();

        // 初始化向量 (IV)
        byte[] iv = new byte[16];
        new java.security.SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // 原文
        String plainText = "Hello, AES CFB Mode!";

        // 加密
        Cipher encryptCipher = Cipher.getInstance("AES/CFB/PKCS5Padding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes());
        System.out.println("加密后的内容: " + javax.xml.bind.DatatypeConverter.printHexBinary(cipherText));

        // 解密
        Cipher decryptCipher = Cipher.getInstance("AES/CFB/PKCS5Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedText = decryptCipher.doFinal(cipherText);
        System.out.println("解密后的内容: " + new String(decryptedText));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值