Java使用Cipher类实现加密的过程详解


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、简单实现加解密

1.1加密

/**
     * 加密
     *
     * @param content    待加密内容
     * @param encryptKey 加密 KEY
     * @return
     */
    public static String encrypt(String content, String encryptKey) throws Exception {
        if (content == null || encryptKey == null) {
            throw new IllegalArgumentException("加密内容 content 和 encryptKey 不能为 null");
        }

        if (encryptKey.length() != KEY_LENGTH) {
            throw new IllegalArgumentException("加密的encryptKey必须为16位");
        }

        // 创建cipher实例 参数按"算法/模式/填充模式" "AES/ECB/PKCS5Padding"
        Cipher cipher = Cipher.getInstance(PADDING);
        // 初始化ciper,
        // (1)opmode :Cipher.ENCRYPT_MODE(加密模式)和 Cipher.DECRYPT_MODE(解密模式)
        // (2)key :密匙,使用传入的盐构造出一个密匙,可以使用SecretKeySpec、KeyGenerator和KeyPairGenerator创建密匙,其中
        // * SecretKeySpec和KeyGenerator支持AES,DES,DESede三种加密算法创建密匙
        // * KeyPairGenerator支持RSA加密算法创建密匙
        // (3)params :使用CBC模式时必须传入该参数,该项目使用IvParameterSpec创建iv 对象
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(DEFAULT_ENCODING), KEY_ALGORITHM));
        /* org.apache.commons.codec.binary.Base64; Base64.encodeBase64String() 解决Base64加密换行问题  */
        // 加密或解密,返回byte数组
        byte[] bytes = cipher.doFinal(content.getBytes(DEFAULT_ENCODING));
        return Base64.encodeBase64String(bytes);

    }

1.2、解密

/**
     * 解密
     *
     * @param content    待解密内容
     * @param decryptKey 解密的 KEY
     * @return
     */
    public static String decrypt(String content, String decryptKey) throws Exception {
        if (content == null || decryptKey == null) {
            throw new IllegalArgumentException("解密内容或解密key不能为null");
        }

        if (decryptKey.length() != KEY_LENGTH) {
            throw new IllegalArgumentException("解密的decryptKey必须为16位");
        }

        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(DEFAULT_ENCODING), KEY_ALGORITHM));
        /*Base64.decodeBase64(content);*/
        byte[] bytes = Base64.decodeBase64(content);
        bytes = cipher.doFinal(bytes);
        return new String(bytes, DEFAULT_ENCODING);

    }

1.3 代码解释

上面简单实现了AES(“AES/CBC/PKCS5Padding”)的加密和解密。可以看到代码中主要的是cipher对象,并有以下调用

(1)新建Cipher对象时需要传入一个参数"AES/CBC/PKCS5Padding"

(2)cipher对象使用之前还需要初始化,共三个参数(“加密模式或者解密模式”,“密匙”,“向量”)

(3)调用数据转换:cipher.doFinal(content),其中content是一个byte数组

实际上Cipher类实现了多种加密算法,在创建Cipher对象时,传入不同的参数就可以进行不同的加密算法。而这些算法不同的地方只是创建密匙的方法不同而已。

如传入“AES/CBC/NoPadding”可进行AES加密,传入"DESede/CBC/NoPadding"可进行DES3加密。具体的后面会介绍到。

2. Cipher类

2.1 Cipher类提供了加密和解密的功能。

该项目使用Cipher类完成aes,des,des3和rsa加密.

获取Cipher类的对象:Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”); 参数按"算法/模式/填充模式",有以下的参数

  • AES/CBC/NoPadding (128)
  • AES/CBC/PKCS5Padding (128)
  • AES/ECB/NoPadding (128)
  • AES/ECB/PKCS5Padding (128)
  • DES/CBC/NoPadding (56)
  • DES/CBC/PKCS5Padding (56)
  • DES/ECB/NoPadding (56)
  • DES/ECB/PKCS5Padding (56)
  • DESede/CBC/NoPadding (168)
  • DESede/CBC/PKCS5Padding (168)
  • DESede/ECB/NoPadding (168)
  • DESede/ECB/PKCS5Padding (168)
  • RSA/ECB/PKCS1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
    (1)加密算法有:AES,DES,DESede(DES3)和RSA 四种
    (2) 模式有CBC(有向量模式)和ECB(无向量模式),向量模式可以简单理解为偏移量,使用CBC模式需要定义一个IvParameterSpec对象
    (3) 填充模式:
  • NoPadding: 加密内容不足8位用0补足8位, Cipher类不提供补位功能,需自己实现代码给加密内容添加0, 如{65,65,65,0,0,0,0,0}
  • PKCS5Padding: 加密内容不足8位用余位数补足8位, 如{65,65,65,5,5,5,5,5}或{97,97,97,97,97,97,2,2}; 刚好8位补8位8

2.2 Cipher对象需要初始化

init(int opmode, Key key, AlgorithmParameterSpec params)
(1)opmode :Cipher.ENCRYPT_MODE(加密模式)和 Cipher.DECRYPT_MODE(解密模式)
(2)key :密匙,使用传入的盐构造出一个密匙,可以使用SecretKeySpec、KeyGenerator和KeyPairGenerator创建密匙,其中

  • SecretKeySpec和KeyGenerator支持AES,DES,DESede三种加密算法创建密匙
  • KeyPairGenerator支持RSA加密算法创建密匙
    (3)params :使用CBC模式时必须传入该参数,该项目使用IvParameterSpec创建iv 对象

2.3 加密或解密

byte[] b = cipher.doFinal(content);
返回结果为byte数组,如果直接使用 new String(b) 封装成字符串,则会出现乱码

可以使用Java Security库中的MessageDigest进行SHA1哈希加密,也可以使用Java Cryptography Extension库中的SecretKeyFactory和KeySpec进行DES加密。以下是使用这两种方法进行加密的示例代码: SHA1加密: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SHA1Util { public static String sha1(String input) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] result = md.digest(input.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : result) { sb.append(String.format("%02x", b)); } return sb.toString(); } } ``` DES加密: ```java import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.security.SecureRandom; public class DESUtil { public static byte[] encrypt(byte[] data, String key) throws Exception { DESKeySpec dks = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(dks); SecureRandom sr = new SecureRandom(); byte[] iv = new byte[8]; sr.nextBytes(iv); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(iv)); byte[] encryptedData = cipher.doFinal(data); byte[] result = new byte[iv.length + encryptedData.length]; System.arraycopy(iv, 0, result, 0, iv.length); System.arraycopy(encryptedData, 0, result, iv.length, encryptedData.length); return result; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值