AES/CBC/PKCS7加密 以及PKCS5加密简单实用

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

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥 

在这里简单介绍下对称加密算法与非对称加密算法的区别。

对称加密算法

加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。

非对称加密算法

加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal。

实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。

 

PKCS7 的工具类,加密之前用十六进制编过码

package com.example.administrator.standardOA.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;

import java.io.UnsupportedEncodingException;


/**
 * Created by Duqianlong on 2018/11/15.
 */


public class AESPKCS7PaddingUtils {
    /**
     * 算法/模式/填充
     **/
    private static final String CipherMode = "AES/CBC/PKCS7Padding";

    // 创建密钥, 长度为128位(16bytes), 且转成字节格式
    private static SecretKeySpec createKey(String key) {

        byte[] data = null;

        if (key == null) {
            key = "";
        }
        StringBuffer sb = new StringBuffer(16);
        sb.append(key);
        while (sb.length() < 16) {
            sb.append("0");
        }
        if (sb.length() > 16) {
            sb.setLength(16);
        }

        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return new SecretKeySpec(data, "AES");
    }

    // 创建初始化向量, 长度为16bytes, 向量的作用其实就是salt
    private static IvParameterSpec createIV(String iv) {

        byte[] data = null;

        if (iv == null) {
            iv = "";
        }
        StringBuffer sb = new StringBuffer(16);
        sb.append(iv);
        while (sb.length() < 16) {
            sb.append("0");
        }
        if (sb.length() > 16) {
            sb.setLength(16);
        }

        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return new IvParameterSpec(data);
    }

    /****************************************************************************/

    // 加密字节数据, 被加密的数据需要提前转化成字节格式
    private static byte[] encrypt(byte[] content, String key, String iv) {

        try {
            SecretKeySpec secretKeySpec = createKey(key);
            IvParameterSpec ivParameterSpec = createIV(iv);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] result = cipher.doFinal(content); // 加密
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    // 加密字符串数据, 返回的字节数据还需转化成16进制字符串
    public static String encrypt(String content, String key) {

        byte[] data = null;
        try {
            data = content.getBytes("UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        data = encrypt(data, key, "text1234");
        return byte2hex(data);
    }


    /****************************************************************************/

    // 解密字节数组
    private static byte[] decrypt(byte[] content, String key) {

        try {
            SecretKeySpec secretKeySpec = createKey(key);
            IvParameterSpec ivParameterSpec = createIV("text1234");
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 解密(输出结果为字符串), 密文为16进制的字符串
    public static String decrypt(String content, String password) {

        byte[] data = null;
        try {
            data = hex2byte(content);
        } catch (Exception e) {
            e.printStackTrace();
        }

        data = decrypt(data, password);
        if (data == null) return null;

        String result = null;
        try {
            result = new String(data, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return result;
    }

    /****************************************************************************/

    // 字节数组转成16进制大写字符串
    private static String byte2hex(byte[] b) {

        String tmp = "";
        StringBuffer sb = new StringBuffer(b.length * 2);
        for (int n = 0; n < b.length; n++) {
            tmp = (Integer.toHexString(b[n] & 0XFF));
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        return sb.toString().toUpperCase();
    }

    // 将16进制字符串转换成字节数组
    private static byte[] hex2byte(String inputString) {

        if (inputString == null || inputString.length() < 2) {
            return new byte[0];
        }
        inputString = inputString.toLowerCase();
        int l = inputString.length() / 2;
        byte[] result = new byte[l];
        for (int i = 0; i < l; ++i) {
            String tmp = inputString.substring(2 * i, 2 * i + 2);
            result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
        }
        return result;
    }

}

 PKCS5 的工具类,加密之前用Base64编过码

package com.example.administrator.standardOA.utils;

import android.util.Base64;

import com.alibaba.fastjson.JSONObject;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Duqianlong on 2018/11/15.
 */

public class AesEncryptUtils {

    //可配置到Constant中,并读取配置文件注入,16位,自己定义
    private static final String KEY = "xxxxxxxxxxxxxxxx";

    //参数分别代表 算法名称/加密模式/数据填充方式
    private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

    /**
     * 加密
     * @param content 加密的字符串
     * @param encryptKey key值
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
        byte[] b = cipher.doFinal(content.getBytes("utf-8"));
        // 采用base64算法进行转码,避免出现中文乱码
//        return Base64.encodeBase64String(b);
        String strBase64 = Base64.encodeToString(b , Base64.DEFAULT);
        return strBase64;

    }

    /**
     * 解密
     * @param encryptStr 解密的字符串
     * @param decryptKey 解密的key值
     * @return
     * @throws Exception
     */
    public static String decrypt(String encryptStr, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
        // 采用base64算法进行转码,避免出现中文乱码
//        byte[] encryptBytes = Base64.decodeBase64(encryptStr);
        byte[] encryptBytes = Base64.decode(encryptStr,Base64.DEFAULT);
        byte[] decryptBytes = cipher.doFinal(encryptBytes);
        return new String(decryptBytes);
    }

    public static String encrypt(String content) throws Exception {
        return encrypt(content, KEY);
    }
    public static String decrypt(String encryptStr) throws Exception {
        return decrypt(encryptStr, KEY);
    }


    public static void main(String[] args) throws Exception {
        Map map=new HashMap<String,String>();
        map.put("loginName","jtliyajuan");
        String content = JSONObject.toJSONString(map);
        System.out.println("加密前:" + content);

        String encrypt = encrypt(content, KEY);
        System.out.println("加密后:" + encrypt);

        String decrypt = decrypt(encrypt, KEY);
        System.out.println("解密后:" + decrypt);
    }

}

使用规则

//加密 pkcs5
    public static String encryption(Map<String, String> map) {
        String encrypt = "";
        Gson gson = new Gson();
        try {
            encrypt = AesEncryptUtils.encrypt(gson.toJson(map));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encrypt;
    }

    //解密 pkcs5
    public static String decryption(String string) {
        String decrypt = "";
        try {
            decrypt = AesEncryptUtils.decrypt(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decrypt;
    }


    //加密
    public static String pkcs7encryption(String string) {
        if (!TextUtils.isEmpty(string)) {
            String text1 = AESPKCS7PaddingUtils.encrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
            return text1;
        } else {
            return "";
        }
    }

    //解密
    public static String kpcs7decryption(String string) {
        if (!TextUtils.isEmpty(string)) {
            String text2 = AESPKCS7PaddingUtils.decrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
            return text2;
        } else {
            return "";
        }
    }

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Java中,可以使用AES/CBC/PKCS7Padding加密方法来对数据进行加密和解密操作。AES是Advanced Encryption Standard的缩写,是一种常用的对称加密算法。CBC是Cipher Block Chaining的缩写,是一种使用前一块密文作为下一块的加密输入的模式。PKCS7Padding是一种填充方式,用于将数据填充到指定块的长度。 要使用AES/CBC/PKCS7Padding加密方法,首先需要选择一个合适的密钥和偏移量。密钥是用于加密和解密数据的关键,偏移量是用于初始化加密器的参数。同时,还需要选择一个合适的填充方式。 在Java中,可以使用JCE(Java Cryptography Extension)库来实现AES/CBC/PKCS7Padding加密方法。可以通过以下步骤进行加密和解密操作: 1. 生成AES密钥:可以使用KeyGenerator类来生成AES密钥。 2. 初始化Cipher对象:可以使用Cipher类来进行加密和解密操作。需要指定使用AES算法和CBC模式,并设置填充方式为PKCS7Padding。 3. 初始化加密器参数:需要使用IvParameterSpec类来初始化加密器的偏移量参数。 4. 设置加密模式和密钥:需要使用Cipher的init方法来设置加密模式(加密或解密)和密钥。 5. 执行加密或解密操作:使用Cipher的doFinal方法来执行加密或解密操作。 使用Java中的AES/CBC/PKCS7Padding加密方法,可以对数据进行安全可靠的加密和解密。但是需要注意保护好密钥的安全性,以免被恶意使用者获取。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值