对称加密(DES、3DES、AES)、非对称加密(RSA、SHA1withRSA)


文章目录

  • 一、加密模式
  • 二、加密填充
  • 三、密钥长度
  • 四、输出
  • 五、Java加解密
  • (1) 加解密
  • (2) 调用


AES是一种对称加密技术 即加密密钥和解密密钥相同,在密码学中又称Rijndael加密法,为比利时密码学家Joan Daemen和Vincent Rijmen所设计



一、加密模式

4种分别是:CBC、CFB、OFB、ECB3种需要向量参数:CBC、CFB、OFB模式;
1种不需要向量参数:ECB模式;

ECB模式是最基本的加密模式,最容易被破解,CBC、CFB、OFB模式的加密过程添加向量后会更加安全。



二、加密填充

5种分别是:pkcs5padding、pkcs7padding、zeropadding、iso10126、ansix923

AES是对数据进行大小相同的分块分割,再进行分块加密;
1.当先对数据分块后,最后一块的数据不一定是完整的,利用填充补齐数据。
2.当先对数据分块后,数据块都是完整的,利用填充再生成一整块数据。

pkcs5padding:固定块的大小为8bytes(64位)
pkcs7padding:块的大小可以在1-255bytes之间。



三、密钥长度

只能是128、192或256位
128位对应16个字节(8位一个字节)、192位对应24个字节、256位对应32个字节;位数越高加密强度越大, 但加密效率越低。

128:aaaaaaaaaaaaaaaa
192:aaaaaaaaaaaaaaaacccccccc
256:aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb



四、输出

2种分别是:base64、hex 对加密后的字节进行base64编码或hex编码



五、Java加解密

以下示例采用:AES/CBC/PKCS5Padding模式,128位秘钥长度和向量长度

(1) 加解密

package com.xxxx.utils;

import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES 加解密
 *
 * AES/CBC/PKCS5Padding
 */
public class AesUtils {

    /**
     * 算法的名称
     */
    private static final String AES = "AES";

    /**
     * 默认 AES/CBC/PKCS5Padding
     *
     * 算法:AES
     * 模式:CBC; 其中CBC、CFB模式需要向量;OFB模式不需要向量
     * 填充:PKCS5Padding
     */
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 编码 utf-8
     */
    private static final String UTF_8 = "utf-8";

    /**
     * 加密
     *
     * @param needEncryptStr 待加密字符串
     * @param key 加密key
     * @param iv 向量
     * @return
     * @throws Exception
     */
    public static String encrypt(String needEncryptStr, String key, String iv) throws Exception {
        byte[] raw = key.getBytes(UTF_8);
        //设置秘钥
        SecretKeySpec keySpec = new SecretKeySpec(raw, AES);
        //设置向量
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
        //初始化加密方式  Cipher.ENCRYPT_MODE 加密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        //加密;   设置为utf-8, 防止中文和英文混合
        byte[] encrypted = cipher.doFinal(needEncryptStr.getBytes(UTF_8));
        //对加密结果HEX编码; 解密时也就需要使用HEX解码;
        byte[] encode = Hex.encode(encrypted);
        // 使用BASE64做转码
        // return new BASE64Encoder().encode(encode);
        return new String(encode).toUpperCase();
    }

    /**
     * 解密
     *
     * @param needDecryptStr 秘钥
     * @param key 秘钥
     * @param iv   向量
     * @param needDecryptStr
     * @return
     * @throws Exception
     */
    public static String decrypt(String needDecryptStr, String key, String iv) throws Exception {
        byte[] raw = key.getBytes(UTF_8);
        //设置秘钥
        SecretKeySpec keySpec = new SecretKeySpec(raw, AES);
        //设置向量
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
        //初始化解密方式  Cipher.DECRYPT_MODE 解密
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        //获取HEX的解码,因为在是加密过程中采用了HEX的编码,所以此步骤需要HEX的解码
        //如果在是加密过程中采用了base64的编码,此步骤就需要base64的解码,
        //HEX和base64 使用一种即可,但需要保持一致
        byte[] encrypted1 = Hex.decode(needDecryptStr);
        // 先用base64解密。与上一行HEX两者选其一。
        // byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);

        //解密
        byte[] original = cipher.doFinal(encrypted1);
        return new String(original, UTF_8);
    }
}

(2) 调用

try{
    String needEncryptStr = "A1B2我们";
    String key = "aaaaaaaaaaaaaaaa";
    String iv  = "aaaaaaaaaaaaaaaa";
    //加密
    String encryptStr = AesUtils1.encrypt(needEncryptStr, key, iv);
    //解密
    String decryptStr = AesUtils1.decrypt(encryptStr, key, iv);
}catch (Exception e){
    
}