CryptoJS中AES实现前后端通用加解密技术

在项目中如果要对前后端传输的数据双向加密, 比如避免使用明文传输用户名,密码等数据。 就需要对前后端数据用同种方法进行加密,方便解密。这里介绍使用 CryptoJS 实现 AES 加解密。

首先需要下载前台使用 CryptoJS 实现 AES 加解密的,所以要先下载组件,下载 CryptoJS-v3.1.2 版本之后,文件中包含components 和 rollups 两个文件夹,components 文件夹下是单个组件,rollups 文件夹下是汇总,引用 rollups 下的 aes.js 文件即可。

已解决解密数据时出现的异常: exception:javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

这里提供 CryptoJS-v3.1.2 的 Github链接

先上后台Java代码:

package com.company.pms.pmsbase.utils;

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

import org.apache.commons.codec.binary.Base64;

public class AesUtil {

 public static void main(String args[]) throws Exception {

  String content = "明文 123 abc";

  //加密
  String encrypted = encrypt(content, KEY, IV);
  //解密
  String decrypted = decrypt(encrypted, KEY, IV);

  System.out.println("加密前:" + content);

  System.out.println("加密后:" + encrypted);

  System.out.println("解密后:" + decrypted);
 }

 private static String KEY = "abcdef0123456789"; // 长度必须是 16

 private static String IV = "abcdef0123456789"; // 长度必须是 16

 /**
  * 加密返回的数据转换成 String 类型
  * @param content 明文
  * @param key 秘钥
  * @param iv 初始化向量是16位长度的字符串
  * @return
  * @throws Exception
  */
 public static String encrypt(String content, String key, String iv) throws Exception {
  // 将返回的加密过的 byte[] 转换成Base64编码字符串 !!!!很关键
  return base64ToString(AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes()));
 }

 /**
  * 将解密返回的数据转换成 String 类型
  * @param content Base64编码的密文
  * @param key 秘钥
  * @param iv 初始化向量是16位长度的字符串
  * @return
  * @throws Exception
  */
 public static String decrypt(String content, String key, String iv) throws Exception {
  // stringToBase64() 将 Base64编码的字符串转换成 byte[] !!!与base64ToString()配套使用
  return new String(AES_CBC_Decrypt(stringToBase64(content), key.getBytes(), iv.getBytes()));
 }

 private static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv));
   byte[] result = cipher.doFinal(content);
   return result;
  } catch (Exception e) {
   System.out.println("exception:"+e.toString());
  }
  return null;
 }

 private static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
   byte[] result = cipher.doFinal(content);
   return result;
  } catch (Exception e) {
   System.out.println("exception:"+e.toString());
  }
  return null;
 }

 /**
  * 字符串装换成 Base64
  */

 public static byte[] stringToBase64(String key) throws Exception {
  return Base64.decodeBase64(key.getBytes());
 }

 /**
  * Base64装换成字符串
  */
 public static String base64ToString(byte[] key) throws Exception {
  return new Base64().encodeToString(key);
 }

}

再上前端代码(需引用 rollups 目录下的 aes.js ):

function encodeAesString(data,key,iv){
 var key = CryptoJS.enc.Utf8.parse(key);
 var iv = CryptoJS.enc.Utf8.parse(iv);
 var encrypted =CryptoJS.AES.encrypt(data,key,{
 iv:iv,
 mode:CryptoJS.mode.CBC,
 padding:CryptoJS.pad.Pkcs7
 });
 //返回的是base64格式的密文
 return encrypted;
}

// encrypted 为是base64格式的密文
function decodeAesString(encrypted,key,iv){
 var key = CryptoJS.enc.Utf8.parse(key);
 var iv = CryptoJS.enc.Utf8.parse(iv);
 var decrypted =CryptoJS.AES.decrypt(encrypted,key,{
 iv:iv,
 mode:CryptoJS.mode.CBC,
 padding:CryptoJS.pad.Pkcs7
 });
 return decrypted.toString(CryptoJS.enc.Utf8);
}

// 测试加、解密
function testAES(){
 var data = "明文 123 abc"; // 明文
 var key = 'abcdef0123456789'; // 密钥 长度16
 var iv = 'abcdef0123456789'; // 密钥 长度16

 console.log("加密前:" + data);

 // 测试加密
 var encrypted = encodeAesString(data,key,iv); // 密文
 console.log("加密后: " + encrypted);

 var decryptedStr = decodeAesString(encrypted,key,iv);
 console.log("解密后: " + decryptedStr);
}

贴上效果图:

中间遇到的问题:

1.  秘钥问题, 秘钥的长度必须为16位, 否则会报错

2. 加密得到的 byte[] 需用使用Base64转换成字符串, 不能直接转成字符串,因为加密所采用的AES, MD5, SHA-256, SHA-512 等等算法,它们是通过对byte[] 进行各种变换和运算,得到加密之后的byte[],那么这个加密之后的 byte[] 结果显然 就不会符合任何一种的编码方案,比如 UTF-8, GBK等,因为加密的过程是任意对byte[]进行运算的。所以你用任何一种编码方案来解码 加密之后的 byte[] 结果,得到的都会是乱码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JS加密插件CryptoJS实现AES加密操作示例

    本文实例讲述了JS加密插件CryptoJS实现AES加密操作.分享给大家供大家参考,具体如下: 最近在做一个项目,考虑到数据的安全性,我们要给数据在传输过程中加密,防止一些恶意的操作以及爬虫抓取数据. 用到的库:CryptoJS 官方地址:https://code.google.com/archive/p/crypto-js/ 首先看看这个CryptoJS的目录结构 主要是两个文件夹,components和rollups 第一个是组件,第二个是汇总. 在汇总文件夹中的文件是在组件一个或多个文件夹

  • JS加密插件CryptoJS实现的Base64加密示例

    本文实例讲述了JS加密插件CryptoJS实现的Base64加密.分享给大家供大家参考,具体如下: 前面一篇<JS加密插件CryptoJS实现的DES加密>介绍了CryptoJS插件进行DES加密操作的方法,这里再来介绍一下CryptoJS进行base64加密的方法: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title>

  • JS使用插件cryptojs进行加密解密数据实例

    本文实例讲述了JS使用插件cryptojs进行加密解密数据.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Testing websoc

  • JavaScript实现的前端AES加密解密功能【基于CryptoJS】

    本文实例讲述了JavaScript实现的前端AES加密解密功能.分享给大家供大家参考,具体如下: js前端AES加密 最近由于项目需求做了一次MITM,突然即使发现使用HTTPS,也不能保证数据传输过程中的安全性. 通过中间人攻击,可以直接获取到Http协议的所有内容. 于是开始尝试做一些简单的加密,在一定程度上保证安全性. 本次采用AES加密数据,所以客户端和服务端使用的相同秘钥.(仅作为演示,正式环境推荐使用RSA) 首先准备一份明文密码和加密使用的KEY var source = "ABC

  • JS加密插件CryptoJS实现的DES加密示例

    本文实例讲述了JS加密插件CryptoJS实现的DES加密.分享给大家供大家参考,具体如下: 前面一篇<JS加密插件CryptoJS实现AES加密操作>介绍了CryptoJS插件的简单配置与使用,这里再来看看CryptoJS实现DES加密的方法: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type

  • CryptoJS中AES实现前后端通用加解密技术

    在项目中如果要对前后端传输的数据双向加密, 比如避免使用明文传输用户名,密码等数据. 就需要对前后端数据用同种方法进行加密,方便解密.这里介绍使用 CryptoJS 实现 AES 加解密. 首先需要下载前台使用 CryptoJS 实现 AES 加解密的,所以要先下载组件,下载 CryptoJS-v3.1.2 版本之后,文件中包含components 和 rollups 两个文件夹,components 文件夹下是单个组件,rollups 文件夹下是汇总,引用 rollups 下的 aes.js

  • 密码系统AES私钥RSA公钥的加解密示例

    目录 前言 百科的诠释 java使用公私钥加解密的实例 前言 密钥是成对存在的,加密和解密是采用不同的密钥(公开密钥),也就是非对称密钥密码系统,每个通信方均需要两个密钥,即公钥和私钥,使用公钥进行加密操作,使用私钥进行解密操作.公钥是公开的,不需要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密.密码学里面博大精深,下面的实例仅供参考 百科的诠释 公钥(Public Key)与私钥(Private Key)是通过一种算法得到的一个密钥对(即一个公钥和一个私钥),公钥是密钥对中公开的部分

  • Java加解密技术系列之RSA详解

    距离上一次写博客感觉已经很长时间了,先吐槽一下,这个月以来,公司一直在加班,又是发版.上线,又是新项目太紧,具体的就不多说了.今天来说说非对称加密真的是太重要了,我们的日常生活中,都离不开非对称加密. 概念 在说 RSA 之前,首先聊聊什么是非对称加密.在讲对称加密的时候,就曾经说过,对称加密算法在加密和解密时使用的是同一个秘钥,加解密双方必须使用同一个密钥才能进行正常的沟通.而非对称加密则不然,非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥. 需要注意的一点,这个公钥和私钥必须是

  • Js通过AES加密后PHP用Openssl解密的方法

    前言 最近遇到的几个网站在提交密码时提交的已经是密文,也就是说在网络上传输的密码是密文,这样提升了密码在网络传输中的安全性. 后端语言加解密已经有很成熟的方案了,前端的话Google之前出过一个crypto-js,为浏览器的js提供了加解密方案.今天一起来了解一下基于AES的前后端加解密流程. Javascript 1.安装npm包 npm install crypto-js 2.加密代码 const CryptoJS = require("crypto-js"); const key

  • AES加解密在php接口请求过程中的应用示例

    在php请求接口的时候,我们经常需要考虑的一个问题就是数据的安全性,因为数据传输过程中很有可能会被用fillder这样的抓包工具进行截获.一种比较好的解决方案就是在客户端请求发起之前先对要请求的数据进行加密,服务端api接收到请求数据后再对数据进行解密处理,返回结果给客户端的时候也对要返回的数据进行加密,客户端接收到返回数据的时候再解密.因此整个api请求过程中数据的安全性有了一定程度的提高. 今天结合一个简单的demo给大家分享一下AES加解密技术在php接口请求中的应用. 首先,准备一个AE

  • AJAX SpringBoot 前后端数据交互的项目实现

    目录 1.Ajax概述 2.基于JQuery的AJAX语法 1. Ajax 概述 Ajax 的英文全称是 ”Asynchronous JavaScript and XML“,即 ”异步的 JavaScript 和 XML“.其核心是通过 JavaScript 的 XMLHttpRequest 对象,以一种异步的方式,向服务器发送数据请求,并且通过该对象接收请求返回的数据,从而实现客户端与服务器端的数据交互. 优点:Ajax 能够刷新指定的页面区域(局部刷新),而不是刷新整个页面,从而减少客户端和

  • 基于 Node.js 实现前后端分离

    基本介绍 首先从一个重要的概念"模板"说起. 广义上来说,web中的模板就是填充数据后可以生成文件的页面. 严格意义上来说,应该是模板引擎利用特定格式的文件和所提供的数据编译生成页面.模板大致分为前端模板(如ejs)和后端模板(如freemarker)分别在浏览器端和服务器端编译. 由于当场有一部分同学对node.js并不是很了解,这里补充一下node.js的相关知识.官网上的给他的定义事件驱动.异步什么的就不说了.这里借用朴灵书上的一张图来解释一下node.js这个玩意的结构.如果懂

  • Spring MVC前后端的数据传输的实现方法

    本篇文章主要介绍了Spring MVC中如何在前后端传输数据.具体内容如下所示: 后端--> 前端 在Spring MVC中这主要通过Model将数据从后端传送到前端,一般的写法为: @RequestMapping(value = "/index", method = RequestMethod.POST) public String index(Model model){ String greeting = "Hello !" model.addAttrib

  • 详解.net core webapi 前后端开发分离后的配置和部署

    背景:现在越来越多的企业都采用了在开发上前后端分离,前后端开发上的分离有很多种,那么今天,我来分享一下项目中得的前后端分离. B/S Saas 项目:(这个项目可以理解成个人中心,当然不止这么点功能) 前端:node.js + vue 后端:.net core webapi 前端安装 node.js 跟创建vue项目这些不是这篇文章的重点,重点在于项目完成后的部署. .net corewebapi创建后,默认就创建了一个wwwroot的文件夹,这个文件夹是用来放置静态文件的,所以,我们可以理解成

  • 详细分析JAVA加解密算法

    加解密算法分析 日常开发中,无论你是使用什么语言,都应该遇到过使用加解密的使用场景,比如接口数据需要加密传给前端保证数据传输的安全:HTTPS使用证书的方式首先进行非对称加密,将客户端的私匙传递给服务端,然后双方后面的通信都使用该私匙进行对称加密传输:使用MD5进行文件一致性校验,等等很多的场景都使用到了加解密技术. 很多时候我们对于什么时候要使用什么样的加解密方式是很懵的.因为可用的加解密方案实在是太多,大家对加解密技术的类型可能不是很清楚,今天这篇文章就来梳理一下目前主流的加解密技术,本篇文

随机推荐