JavaScript与Java前后端AES加解密
JavaScript前端与Java后端AES加密与解密
在实际项目开发中针对一些敏感信息的数据为了保证安全,前后台之间的传输需要以密文的形式传递,这就需要前台将入参数据加密传递到后台,后台将密文数据进行解密,所有通过以登录为案例说明数据的加密与解密
1、AES加密简介
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
(一)、后端代码实现
2、pom依赖
这里主要用到JDK自身的加密规则并依赖第三方jar包,pom依赖如下
<!-- https://mvnrepository.com/artifact/com.xiaoleilu/hutool-all --> <dependency> <groupId>com.xiaoleilu</groupId> <artifactId>hutool-all</artifactId> <version>3.2.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency>
3、Java加密解密工具类:
1 package com.sun.mall.util; 2 3 import java.math.BigInteger; 4 5 import javax.crypto.Cipher; 6 import javax.crypto.KeyGenerator; 7 import javax.crypto.spec.SecretKeySpec; 8 9 import org.apache.commons.codec.binary.Base64; 10 11 import com.sun.mall.constants.IResultCode; 12 import com.xiaoleilu.hutool.util.StrUtil; 13 14 import sun.misc.BASE64Decoder; 15 16 /** 17 * AES的加密和解密 18 * @ClassName: AesUtil 19 * @author sunt 20 * @date 2017年11月30日 21 * @version V1.0 22 */ 23 public class AesUtil { 24 25 //算法 26 private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding"; 27 28 /** 29 * aes解密 30 * @param encrypt 内容 31 * @return 32 * @throws Exception 33 */ 34 public static String aesDecrypt(String encrypt) { 35 try { 36 return aesDecrypt(encrypt, IResultCode.AES_KEY); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 return ""; 40 } 41 } 42 43 /** 44 * aes加密 45 * @param content 46 * @return 47 * @throws Exception 48 */ 49 public static String aesEncrypt(String content) { 50 try { 51 return aesEncrypt(content, IResultCode.AES_KEY); 52 } catch (Exception e) { 53 e.printStackTrace(); 54 return ""; 55 } 56 } 57 58 /** 59 * 将byte[]转为各种进制的字符串 60 * @param bytes byte[] 61 * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 62 * @return 转换后的字符串 63 */ 64 public static String binary(byte[] bytes, int radix){ 65 return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 66 } 67 68 /** 69 * base 64 encode 70 * @param bytes 待编码的byte[] 71 * @return 编码后的base 64 code 72 */ 73 public static String base64Encode(byte[] bytes){ 74 return Base64.encodeBase64String(bytes); 75 } 76 77 /** 78 * base 64 decode 79 * @param base64Code 待解码的base 64 code 80 * @return 解码后的byte[] 81 * @throws Exception 82 */ 83 public static byte[] base64Decode(String base64Code) throws Exception{ 84 return StrUtil.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code); 85 } 86 87 88 /** 89 * AES加密 90 * @param content 待加密的内容 91 * @param encryptKey 加密密钥 92 * @return 加密后的byte[] 93 * @throws Exception 94 */ 95 public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception { 96 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 97 kgen.init(128); 98 Cipher cipher = Cipher.getInstance(ALGORITHMSTR); 99 cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); 100 101 return cipher.doFinal(content.getBytes("utf-8")); 102 } 103 104 105 /** 106 * AES加密为base 64 code 107 * @param content 待加密的内容 108 * @param encryptKey 加密密钥 109 * @return 加密后的base 64 code 110 * @throws Exception 111 */ 112 public static String aesEncrypt(String content, String encryptKey) throws Exception { 113 return base64Encode(aesEncryptToBytes(content, encryptKey)); 114 } 115 116 /** 117 * AES解密 118 * @param encryptBytes 待解密的byte[] 119 * @param decryptKey 解密密钥 120 * @return 解密后的String 121 * @throws Exception 122 */ 123 public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception { 124 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 125 kgen.init(128); 126 127 Cipher cipher = Cipher.getInstance(ALGORITHMSTR); 128 cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES")); 129 byte[] decryptBytes = cipher.doFinal(encryptBytes); 130 return new String(decryptBytes); 131 } 132 133 134 /** 135 * 将base 64 code AES解密 136 * @param encryptStr 待解密的base 64 code 137 * @param decryptKey 解密密钥 138 * @return 解密后的string 139 * @throws Exception 140 */ 141 public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { 142 return StrUtil.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); 143 } 144 145 /** 146 * 测试 147 * 前端js将参数加密提交到后台如何解密 148 * 首先获取服务端的私钥:将客户端的公钥加密后获得的结果 149 * 通过服务端的私钥和客户端传递的加密字符串即可实现解密 150 */ 151 public static void main(String[] args) throws Exception { 152 String content = "456"; 153 System.out.println("加密前:" + content); 154 System.out.println("加密密钥和解密密钥:" + IResultCode.AES_KEY); 155 String encrypt = aesEncrypt(content, IResultCode.AES_KEY); 156 System.out.println("加密后:" + encrypt); 157 String decrypt = aesDecrypt(encrypt, IResultCode.AES_KEY); 158 System.out.println("解密后:" + decrypt); 159 //js加密后的字符串: lkqsgKHH7OkhIa0tISMtuQ== 160 String jsData = aesDecrypt("lkqsgKHH7OkhIa0tISMtuQ==", IResultCode.AES_KEY); 161 System.out.println("前端数据解密后的值:" + jsData); 162 163 } 164 }
package com.sun.mall.constants; /** * 结果码常量 * @ClassName: IResultCode * @author sunt * @date 2017年11月24日 * @version V1.0 */ public interface IResultCode { /** * 成功 */ String S_OK = "1"; /** * 失败 */ String S_FAIL = "0"; /** * 错误默认提示 */ String S_FAIL_TIPS = "系统开小差了,请稍后再试"; /** * 成功提示 */ String S_OK_TIPS = "加载成功"; /** * 用户名非空提示 */ String USER_EMPT_TIPS = "请输入用户名"; /** * 密码非空提示 */ String PWD_EMPT_TIPS = "请输入密码"; /** * 验证码非空提示 */ String VERIFYCODE_EMPT_TIPS = "请输入验证码"; /** * 验证码过期提示 */ String VERIFYCODE_EXPIRE_TIPS = "验证码已失效,请重新获取"; /** * 验证码错误提示 */ String VERIFYCODE_ERROR_TIPS = "验证码输入错误"; /** * 用户名或密码错误 */ String USER_PWD_ERROR_TIPS = "用户名或密码错误"; /** * 秘钥(需要前端和后端保持一致) */ String AES_KEY = "bWFsbHB3ZA==WNST"; }
4、测试加密解密结果
需要注意一点:秘钥长度必须为16位
(二)、前端代码实现
1、第三方加密js下载链接:javascript:;http://download.csdn.net/download/u010427935/10139277
链接失效请发邮件(wnst1990@126.com)告知
2、js加密解密代码
1 /** 2 * 加密(依赖aes.js) 3 * @param word 加密的字符串 4 * @returns {*} 5 */ 6 function encrypt(word){ 7 var key = CryptoJS.enc.Utf8.parse("bWFsbHB3ZA==WNST"); 8 var srcs = CryptoJS.enc.Utf8.parse(word); 9 var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); 10 return encrypted.toString(); 11 } 12 13 /** 14 * 解密 15 * @param word 解密的字符串 16 * @returns {*} 17 */ 18 function decrypt(word){ 19 var key = CryptoJS.enc.Utf8.parse("bWFsbHB3ZA==WNST"); 20 var decrypt = CryptoJS.AES.decrypt(word, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); 21 return CryptoJS.enc.Utf8.stringify(decrypt).toString(); 22 }
3、具体使用
以登录为例,我们需要将登录的参数进行加密,具体代码如下
浏览器查看POST发送的数据
4、后台解密
后台以bean形式接收数据,将密文进行解密
这样就可以实现前台数据的加密后台将密文解密实现系统的相对安全性
最新同步更新地址:https://www.sunnyblog.top/
感谢您花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让博主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下左下角“推荐”按钮,您的“推荐”将是我最大的写作动力!另外您也可以选择【关注我】,可以很方便找到我!
本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/sunny1009 欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利!