javascript 解密_Javascript中的AES加密和Java中的解密

javascript 解密

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 ,它们具有执行加密和解密的通用代码。 这里的this.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加密和解密

DemoApplication.java作为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

javascript 解密

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

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

相关文章

英文标点符号大全

标点符号英文中文名称未知反撇号’apostrophe撇号&#xff0c;缩写及所有格符号plus加号&#xff1b;正号-minus减号&#xff1b;负号plus or minus正负号is multiplied by乘号is divided by除号&#xff1d;is equal to等于号≠is not equal to不等于号≡is equivalent to全等…

Linux 系统下显示文件内容(查看文件内容)的命令 more/less/cat/head/tail 比较

命令说明more建议用于查看内容较长的文本文件&#xff0c;内容可以分屏显示&#xff0c;并且支持在显示时定位关键字cat建议用于查看内容较少的文本文件。当文件较大时&#xff0c;文本在屏幕上迅速闪过&#xff08;滚屏&#xff09;&#xff0c;用户往往看不清所显示的内容。因…

mysql子分区多少层_MySQL 子分区-阿里云开发者社区

介绍子分区其实是对每个分区表的每个分区进行再次分隔&#xff0c;目前只有RANGE和LIST分区的表可以再进行子分区&#xff0c;子分区只能是HASH或者KEY分区。子分区可以将原本的数据进行再次的分区划分。一、创建子分区子分区由两种创建方法&#xff0c;一种是不定义每个子分区…

gradle 编译java_Java的Gradle依赖关系,使用编译还是实现?

gradle 编译java当我向一位同事解释如何将Gradle用于Java项目时&#xff08;他正在远离Maven &#xff09;&#xff0c;我们遇到了各种代码示例。 一些示例将编译配置用于依赖项&#xff0c;而其他示例则使用Implements和api 。 dependencies { compile commons-httpclient:co…

Linux 命令之 typeset -- 声明 shell 变量,设置变量的属性

文章目录一、命令介绍二、常用选项三、命令示例&#xff08;1&#xff09;定义关联数组并访问一、命令介绍 typeset 命令是 bash 的内建命令&#xff0c;是命令 declare 的别名&#xff0c;两者是完全一样的&#xff0c;用来声明 shell 变量&#xff0c;设置变量的属性。 用于…

git log 迁移_现场故事:从Log4J迁移到Log4J2

git log 迁移通过从您的应用程序学习企业APM产品&#xff0c;发现更快&#xff0c;更有效的性能监控。 参加AppDynamics APM导览&#xff01; 与许多Java应用程序一样&#xff0c;AppDynamics Java代理广泛使用日志记录。 多年来&#xff0c;我们一直使用Log4J作为我们的日志记…

mysql firebird 性能_Firebird, MySQL 与 PostgreSQL 代码质量对比

今天看到一篇文章 - “Firebird, MySQL 与 PostgreSQL 代码质量对比”- 关于三个开源 RDBMS 的静态分析比较。主要内容A few words about the projectsFirebirdMySQLPostgreSQLPVS-StudioComparison criteriaWhy "head-on" comparison is not a good ideaAn alterna…

Linux 命令之 let -- bash 中用于计算的工具,用于执行一个或多个表达式

文章目录一、命令介绍二、命令示例自增操作自减操作shell 脚本中的运算表达式一、命令介绍 let 命令是 BASH 中用于计算的工具&#xff0c;用于执行一个或多个表达式&#xff0c;变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符&#xff0c;则必须引…

sun jdk 与jdk_Sun过去的世界中的JDK 11和代理

sun jdk 与jdk使用JDK 11后&#xff0c;就sun.misc.Unsafe的第一种方法。 其中&#xff0c; defineClass方法已删除。 代码生成框架通常使用此方法在现有的类加载器中定义新的类。 尽管此方法易于使用&#xff0c;但它的存在也使JVM本质上不安全&#xff0c;正如其定义类的名称…

php mysql上传多张图片_PHP开发之多个文件上传到MySql数据库(一)

前面的章节我们介绍了用PHP实现上传一个文件的教程。朋友们就会有疑问&#xff0c;怎么样才能上传多张多个文件到数据库&#xff1f;重点在于放入几个文件以后点击提交上传之后所有的文件一起上传&#xff0c;并且每个文件都给一个新的路径。提供一种思路&#xff1a;先获取每个…

jdk只有一个java进程_JDK 10:从Java访问Java应用程序的进程ID

jdk只有一个java进程StackOverflow.com上一个普遍的问题是&#xff1a;“ Java程序如何获得自己的进程ID&#xff1f; 与该问题相关的几个答案包括解析ManagementFactory返回的String 。 getRuntimeMXBean&#xff08;&#xff09; 。 getName&#xff08;&#xff09; [但是可…

Shell 脚本生成不重复的随机数

#!/bin/bash #AUTHOR:AN #DATE:2019-3-24 #Describe:Generate No-Repeat Random-Number #Method:如生成3~7的随机数&#xff0c;先生成0~4&#xff08;7-3&#xff09;的随机数&#xff0c;再加上3&#xff08;起始值&#xff09;来修正 #####################################…

python if语句能否判断中文_Python“if”语句被忽略

如果满足多个条件(“or”)中的一个&#xff0c;我将触发Python中的循环。脚本似乎跳过了“if”语句并在不满足所需条件的情况下进入内部循环。在编码# Begin TestCase# Main logic: execute RemoteController macro, if expected state true, set Success, else: Failfor macr…

payara 创建 集群_Payara Micro在Oracle应用容器云上

payara 创建 集群在此博客文章中&#xff0c;我将描述如何将打包在Payara Microber -jar中的CloudEE Duke应用程序部署到Oracle Application Container Cloud 。 在Oracle Application Container Cloud中进行部署所需的部署工件是一个ZIP归档文件&#xff0c;其中包含应用程序…

shell 脚本书写规范

表达式中的运算符之间不允许空格&#xff0c;例如&#xff1a; [roothtlwk0001host ~]# sum 200 300 sum: : 没有那个文件或目录 sum: 200: 没有那个文件或目录 sum: : 没有那个文件或目录 sum: 300: 没有那个文件或目录从上面的输出结果可知&#xff0c;每项前后出现空格&a…

python可以用来整理表格吗_Python将多份excel表格整理成一份表格

利用Python将多份excel表格整理成一份表格&#xff0c;抛弃过去逐份打开复制粘贴的方式。直接附上代码&#xff1a; import xlrdimport xlwtimport osfrom xlutils.copy import copyimport os.pathfrom xlwt import *dir input("输入文件路径\n");start_row input(…

Linux 环境变量启动过程/配置文件的读取过程

环境变量配置文件 对所有用户都起作用 /etc/profile/etc/profile.d/*.sh/etc/bashrc 对当前用户起作用 配置文件在用户家目录下&#xff0c;即用户的主目录下。 ~/.bash_profile~/.bashrc 环境变量启动过程 新进程启动后先将父进程的全局性的环境变量复制一份到自己的栈…

azure blob_使用Azure Blob存储托管Maven工件

azure blob如果您使用Microsoft Azure并且将Java用于项目&#xff0c;则Azure Blob存储是托管团队工件的理想场所。 它很容易设置&#xff0c;而且很便宜。 如果您对它们的功能不特别感兴趣&#xff0c;那么它比设置现有存储库选项&#xff08;jfrog&#xff0c;nexus&#xf…

angular ngoninit 刷新html页面_web前端入门到实战:实现html页面自动刷新

使用场景&#xff1a;页面需要定时刷新&#xff0c;实时加载数据&#xff0c;需要实时查看监控数据&#xff08;H5中的WebSocket和SSE可以实现局部刷新&#xff09;一定时间之后跳转到指定页面&#xff08;登录注册之类&#xff09;前端开发使用伪数据调试html页面&#xff08;…