Javascript中的AES加密和Java中的解密

AES代表高级加密系统,它是一种对称加密算法,很多时候我们需要在客户端加密一些纯文本(例如密码)并将其发送到服务器,然后由服务器解密以进行进一步处理.AES加密和解密更加容易在相同的平台(例如Android客户端和Java服务器)中实现,但有时在跨平台环境(例如Java客户端和Java Server)(例如在Spring MVC框架中)中解密AES加密密码变得颇具挑战性,因为如果任何系统默认值都不匹配,那么解密将失败。

在本文中,我们将使用spring mvc和angular js客户端创建一个应用程序。 我们将有一个登录页面,其中包含用户名和密码的表单输入。 在将密码发送到服务器之前,将使用CryptoJS在javascript中对密码进行加密,并且将在java中解密相同的加密密码,并进行比较以匹配密码。我们将在javascript中生成salt和IV,然后生成使用PBKDF2函数从密码,盐和密钥大小中获取密钥,之后我们将使用key和IV对明文进行加密,并使用Java对其进行解密,因此基本上我们将开发一种与Java和Java互操作的AES加密机制。 Javascript。

在继续进行之前,让我们澄清一件事,即该机制仅在数据的有线传输过程中(最有可能)增加了一种额外的安全性,但没有提供完全的证明安全性。 如果您不使用SSL,则攻击者可以执行中间人攻击,并通过为用户提供其他密钥来窃取数据。

项目结构

我们有一个弹簧靴和角度Js Web应用程序设置。以下是结构。

JavaScript中的Aes加密

对于javascript中的AES加密,我们导入了两个js文件crypto.jspbkdf2.js 。我们拥有AesUtil.js ,它们具有执行加密和解密的通用代码。 这里的keySize是密钥的大小,以4字节为单位。因此,要使用128位密钥,我们将位数除以32得到了用于CryptoJS的密钥大小。

AesUtil.js

var AesUtil = function(keySize, iterationCount) {this.keySize = keySize / 32;this.iterationCount = iterationCount;
};AesUtil.prototype.generateKey = function(salt, passPhrase) {var key = CryptoJS.PBKDF2(passPhrase, CryptoJS.enc.Hex.parse(salt),{ keySize: this.keySize, iterations: this.iterationCount });return key;
}AesUtil.prototype.encrypt = function(salt, iv, passPhrase, plainText) {var key = this.generateKey(salt, passPhrase);var encrypted = CryptoJS.AES.encrypt(plainText,key,{ iv: CryptoJS.enc.Hex.parse(iv) });return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}AesUtil.prototype.decrypt = function(salt, iv, passPhrase, cipherText) {var key = this.generateKey(salt, passPhrase);var cipherParams = CryptoJS.lib.CipherParams.create({ciphertext: CryptoJS.enc.Base64.parse(cipherText)});var decrypted = CryptoJS.AES.decrypt(cipherParams,key,{ iv: CryptoJS.enc.Hex.parse(iv) });return decrypted.toString(CryptoJS.enc.Utf8);
}

JavaScript中的密码加密

单击提交按钮后,将调用logMeIn()方法。 该方法将使用AesUtil.js定义的通用代码来加密密码并发出POST请求以验证密码。发送的密码将以iv::salt::ciphertext的形式在服务器端,java将解密密码并在响应中发送解密的密码,该密码将显示在警报框中。

var app = angular.module('demoApp', []);
app.controller('loginController', ['$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {$scope.logMeIn = function(){if(!$scope.userName || !$scope.password){$scope.showMessage("Missing required fields.", false);return;}var iv = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);var salt = CryptoJS.lib.WordArray.random(128/8).toString(CryptoJS.enc.Hex);var aesUtil = new AesUtil(128, 1000);var ciphertext = aesUtil.encrypt(salt, iv, $('#key').text(), $scope.password);var aesPassword = (iv + "::" + salt + "::" + ciphertext);var password = btoa(aesPassword);var data = {userName: $scope.userName,password: password}$http.post('/login',data).then(function (response){if(response.status === 200){alert("Password is " + response.data.password);}else {alert("Error occurred");}})};}]);

Java中的AES解密

首先,让我们实现将拦截登录请求的控制器类。 这里我们已经对该密钥进行了硬编码,该密钥将由服务器唯一生成,并针对每个登录请求发送给客户端。 客户端将使用相同的密钥,而加密和服务器将使用相同的密钥进行解密。请确保密钥长度为16,因为我们使用的是128位加密。 记住我们从客户端发送的加密文本的格式– iv::salt::ciphertext 。 文本以相同格式解密。 我们已经有IV,salt和密文。

package com.example.demo.controller;import com.example.demo.model.Credentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;@Controller
public class WelcomeController {private static final Logger LOGGER = LoggerFactory.getLogger(WelcomeController.class);@RequestMapping(value={"/login"},method = RequestMethod.GET)public String loginPage(HttpServletRequest request){LOGGER.info("Received request for login page with id - " + request.getSession().getId());String randomKey = UUID.randomUUID().toString();//String uniqueKey = randomKey.substring(randomKey.length()-17, randomKey.length() -1);String uniqueKey = "1234567891234567";request.getSession().setAttribute("key", uniqueKey);return "index";}@RequestMapping(value={"/login"},method = RequestMethod.POST)public @ResponseBody ResponseEntity login(@RequestBody Credentials credentials, HttpServletRequest request) {String decryptedPassword =  new String(java.util.Base64.getDecoder().decode(credentials.getPassword()));AesUtil aesUtil = new AesUtil(128, 1000);Map map = new HashMap<>();if (decryptedPassword != null && decryptedPassword.split("::").length == 3) {LOGGER.info("Password decrypted successfully for username - " + credentials.getUserName());String password = aesUtil.decrypt(decryptedPassword.split("::")[1], decryptedPassword.split("::")[0], "1234567891234567", decryptedPassword.split("::")[2]);map.put("password", password);}return new ResponseEntity<>(map, HttpStatus.OK);}}

以下是用于AES加密和解密的java util类。您可以在java中遵循AES加密和解密,以获取有关以下实现的更多详细说明。

AesUtil.java
package com.example.demo.controller;import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;public class AesUtil {private final int keySize;private final int iterationCount;private final Cipher cipher;public AesUtil(int keySize, int iterationCount) {this.keySize = keySize;this.iterationCount = iterationCount;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");}catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw fail(e);}}public String decrypt(String salt, String iv, String passphrase, String ciphertext) {try {SecretKey key = generateKey(salt, passphrase);byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));return new String(decrypted, "UTF-8");}catch (UnsupportedEncodingException e) {return null;}catch (Exception e){return null;}}private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {try {cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));return cipher.doFinal(bytes);}catch (InvalidKeyException| InvalidAlgorithmParameterException| IllegalBlockSizeException| BadPaddingException e) {return null;}}private SecretKey generateKey(String salt, String passphrase) {try {SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");return key;}catch (NoSuchAlgorithmException | InvalidKeySpecException e) {return null;}}public static byte[] base64(String str) {return Base64.decodeBase64(str);}public static byte[] hex(String str) {try {return Hex.decodeHex(str.toCharArray());}catch (DecoderException e) {throw new IllegalStateException(e);}}private IllegalStateException fail(Exception e) {return null;}}

测试AES加密和解密

作为Java应用程序运行DemoApplication.java并点击http:// localhost:8080 。 登录页面出现后,您可以输入用户名和密码,然后单击“提交”按钮,您可以在警报中看到解密的密码。


/>

结论

在本文中,我们讨论了可与Java和Javascript互操作的AES加密。 我们使用Crypto.js库在javascript中执行此加密。 完整的源代码可以在这里找到。如果您有任何要添加或共享的内容,请在下面的评论部分中共享。

翻译自: https://www.javacodegeeks.com/2018/03/aes-encryption-in-javascript-and-decryption-in-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

toString()方法使用

toString()方法在Object类中定义&#xff0c;其返回值是String类型&#xff0c;返回类名和它的引用地址。在进行String与其它类型数据的连接操作时&#xff0c;自动调用toString()方法。 Account account new Account(); System.out.println(account); //com.atyeman.Account…

php 睡眠,php输出与sleep()

您要实现的是从PHP向浏览器的增量输出.这是否可实现取决于您的服务器以及您如何调用PHP.FastCGI下的PHP当PHP在FastCGI下而不是作为Apache模块运行时,你可能更容易遇到这种问题,因为服务器和PHP进程之间的耦合并不紧密耦合.一旦数据离开PHP进程,FastCGI通信就使用输出缓冲,只有…

Java面向对象(14)--包装类的使用

针对八种基本数据类型定义相应的引用类型—包装类&#xff08;封装类&#xff09;&#xff0c;有了类的特点&#xff0c;就可以调用类中的方法。 基本数据类型 <——> 包装类&#xff0c;String——>包装类 ①装 int num 9; Integer int1 new Integer(num); Syste…

php读取mp3信息,PHP获取MP3的媒体标签信息

PHP如何获取MP3的媒体标签信息&#xff1f;本文主要介绍了PHP获取音频文件的相关信息的相关资料。希望对大家有所帮助。项目需求&#xff1a;现在有一个音频文件上传的功能&#xff0c;在上传后PHP需要获取这个音频文件的相关信息&#xff0c;例如&#xff1a;时长等&#xff0…

资源泄漏如何处理_处理缓慢的资源泄漏

资源泄漏如何处理使用Java监视器查找资源泄漏 查找缓慢的资源泄漏是使应用程序服务器长时间保持正常运行的关键。 在这里&#xff0c;我解释了如何使用Java监视器来发现缓慢的资源泄漏&#xff0c;以及如何验证它们是否是实际泄漏&#xff0c;而不仅仅是额外的预分配到某些HTTP…

Integer包装类特殊之处

Integer内部定义了IntegerCache结构&#xff0c;IntegerCache中定义了 Integer[]&#xff0c;保存了从-128~127范围的整数。如果我们使用自动装箱的方式&#xff0c;给Integer赋值的范围在 -128~127范围内时&#xff0c;可以直接使用数组中的元素&#xff0c;不再去new了。目的…

php中间件怎么使用,laravel框架中间件简单使用方法示例

本文实例讲述了laravel框架中间件简单使用方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;laravel内置了一个中间件来验证用户是否经过认证&#xff0c;如果用户没有经过认证&#xff0c;中间件会将用户重定向到登录页面&#xff0c;否则如果用户经过认证&#xf…

在Spring WebFlux中创建多个RouterFunction

在这篇文章中&#xff0c;我们将研究在Spring WebFlux中为不同的逻辑域定义多个路由器功能。 如果您正在创建“微服务”&#xff0c;则可能不会出现问题&#xff0c;因为您很可能仅在每个服务的单个域中工作&#xff0c;但是如果不是这样&#xff0c;则可能需要在应用程序中包含…

cstart做int型转换运算Java,java 实验报告1.docx

甘肃政法学院本科生实验报告(一)姓名:俞晓学院:信息工程学院专业:信息管理与信息系统班级:13级信管班实验课程名称:JAVA SE课程实验指导教师&#xff1a;李瑞生 教师实验成绩&#xff1a;实验日期: 2015 年 3 月 24 日开课时间&#xff1a; 2014-2015 学年 第二 学期甘肃政法学…

Java面向对象(15)--static关键字静态理解与使用

类属性作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变&#xff0c;将这些属性设置为类属性。如果方法与调用者无关&#xff0c;则这样的方法通常被声明为类方法&#xff0c;由于不需要创建对象就可以调用类方法&#xff0c;从而简化了方法的调用…

JSON补丁:JSON-P 1.1概述系列

Java EE 8包括对JSON处理API的更新&#xff0c;并使其与JSON的最新IEFT标准保持同步。 他们是&#xff1a; JSON指针 RFC 6901 JSON补丁 RFC 6902 JSON合并修补程序RFC 7396 我将在这个迷你系列中涵盖这些主题。 入门 要开始使用JSON-P&#xff0c;您将需要Maven中央存储库…

Java面向对象(16)--单例(Singleton)设计模式

所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象&#xff0c;我们首先必须将类的构造器的访问权限设…

mac php 超时,PHP---Mac上开启php错误提示

发现在使用mac 上 PHP开发项目的时候&#xff0c;程序代码错误的时候没有错误提示&#xff0c;只是提示白板。研究和查找资料才调整了一下; 步骤如下&#xff1a;1.找到php.ini文件如图所示&#xff1a;1)找到 display_errors Off &#xff0c;把Off 改为 On . 最后为 display…

tomcat 轮询_用Spring长轮询Tomcat

tomcat 轮询就像喜剧演员弗兰基 豪威尔 &#xff08; Frankie Howerd&#xff09;所说的“噢&#xff0c;小姐小姐” &#xff0c;但足够多的英国影射和双重诱惑&#xff0c;因为长轮询Tomcat对隔壁的闷气不是某种性的偏见&#xff0c;这是一种技术&#xff08;或更像是一种hac…

单例(Singleton)设计模式应用场景

网站的计数器&#xff0c;一般也是单例模式实现&#xff0c;否则难以同步。 应用程序的日志应用&#xff0c;一般都使用单例模式实现&#xff0c;这一般是由于共享的日志文件一直处于打开状态&#xff0c;因为只能有一个实例去操作&#xff0c;否则内容不好追加。 数据库连接…

免费网络研讨会:Java应用程序中的吞咽异常

1月30日参加我们的网络研讨会&#xff0c;以发现Java应用程序中的“隐藏”异常。 如果一棵树落在森林中&#xff0c;但是没有写到原木上&#xff0c;它会发出声音吗&#xff1f; 答案是肯定的。 这些类型的错误可能会对用户体验造成严重影响&#xff0c;而没有根本原因的可见性…

php bloginfo templatedirectory,WordPress函数:bloginfo(显示博客信息)

描述显示你的博客信息&#xff0c;大部分都是显示WordPress管理界面的 用户资料 和 常规设置 中的信息。它可以在模板文件的任何地方使用。一般 bloginfo() 都是用来直接在浏览器中输出内容的。如果你需要在PHP中返回值的话&#xff0c;那么请用 get_bloginfo()。用法<?php…

Java面向对象(17)--类代码块

静态代码块&#xff1a;用static 修饰的代码块 ①可以有输出语句。 ②可以对类的属性、类的声明进行初始化操作。 ③不可以对非静态的属性初始化&#xff0c;即&#xff1a;不可以调用非静态的属性和方法。 ④ 静态代码块随着类的加载而加载并执行&#xff0c;类加载一次&…

js 和java有关系吗,javascript和JAVA有什么关系

2017-07-28Java调用javascriptpackage co。test;import java。io。FileReader;import java。io。LineNumberReader;import org。mozilla。 javascript。Context;import org。mozilla。javascript。Function;import org。mozilla。javascript。Scriptable;public class JSExplor…

gson 入门_Google GSON入门

gson 入门在Java世界中&#xff0c;JSON已成为事实上的XML数据交换格式标准&#xff0c;因为它的易用性和传输效率高。 如果您不了解JSON&#xff0c;那就是Javascript对象表示法&#xff0c;这是一种基于文本的数据交换格式&#xff0c;是名称-值的集合&#xff0c;其中名称严…