Node Java相互使用AES-128-GCM对数据进行加密解密实现_宋峥清的博客-程序员宅基地

技术标签: Java  加密解密  node.js  前端(js/jsp/html/vue...)  AES-128-GCM  

在这里插入图片描述

Node代码

let crypto = require('crypto');

//偏移量 16位
const iv = "0123456789ABCDEF";
//密钥
const key = "0123456789ABCDEF";


//加密
function encodeAes(word) {
    
    if (!word) {
    
        return ''
    }
    if (typeof word != 'string') {
    
        word = JSON.stringify(word)
    }

    const md5 = crypto.createHash('md5');
    const result = md5.update(key).digest();
    const cipher = crypto.createCipheriv('aes-128-gcm', result, iv);
    const encrypted = cipher.update(word, 'utf8');
    const finalstr = cipher.final();
    const tag = cipher.getAuthTag();
    const res = Buffer.concat([encrypted, finalstr, tag]);
    return res.toString('base64');
}

//解密
function decodeAes(word) {
    
    if (!word) {
    
        return ''
    }
    const md5 = crypto.createHash('md5');
    const result = md5.update(key).digest();
    const decipher = crypto.createDecipheriv('aes-128-gcm', result, iv);
    const b = Buffer.from(word, 'base64')
    decipher.setAuthTag(b.subarray(b.length - 16));
    const str = decipher.update(Buffer.from(b.subarray(0, b.length - 16), 'hex'));
    const fin = decipher.final();
    const decryptedStr = new TextDecoder('utf8').decode(Buffer.concat([str, fin]))
    try {
    
        return JSON.parse(decryptedStr);
    } catch (e) {
    
        return decryptedStr
    }
}


let encodeStr = encodeAes('hello word');
console.log('加密后:' + encodeStr);
let decodeStr = decodeAes(encodeStr);
console.log('解密后:' + decodeStr);

Java代码

import java.security.MessageDigest;

import java.security.Security;

import java.util.Base64;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * @Description 
 * @Date 13:43 2020/12/8
 **/
public class AesGcmUtil {
    

    
    /**
     * @Description  16位的密钥
     * @Date 13:43 2020/12/8
     **/
    public static final String KEY = "0123456789ABCDEF";

    private static final String IV = "0123456789ABCDEF";

    private static final String ALGORITHMSTR = "AES/GCM/NoPadding";

    private static final String DEFAULT_CODING = "utf-8";

    /**
     * 如果报错java.security.NoSuchProviderException: no such provider: BC,那么需要加上这一段,同时需要bcprov-jdk15on.jar
     */
    static {
    
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * @Description 加密
     * @Date 14:25 2020/12/7
     **/
    public static String aesEncrypt(String content) throws Exception {
    
        byte[] input = content.getBytes(DEFAULT_CODING);
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(KEY.getBytes(DEFAULT_CODING));
        SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
        IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes(DEFAULT_CODING));
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR, "BC");
        cipher.init(Cipher.ENCRYPT_MODE, skc, ivspec);
        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
        return Base64.getEncoder().encodeToString(cipherText);
    }


    /**
     * @Description 解密
     * @Date 14:26 2020/12/7
     **/
    public static String aesDecrypt(String tmp) throws Exception {
    
        byte[] keyb = KEY.getBytes(DEFAULT_CODING);
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(keyb);
        SecretKeySpec skey = new SecretKeySpec(thedigest, "AES");
        IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes(DEFAULT_CODING));
        Cipher dcipher = Cipher.getInstance(ALGORITHMSTR, "BC");
        dcipher.init(Cipher.DECRYPT_MODE, skey, ivspec);
        byte[] clearbyte = dcipher.doFinal(Base64.getDecoder().decode(tmp));
        return new String(clearbyte, DEFAULT_CODING);
    }

    public static void main(String[] args) throws Exception {
    
        String origin = "这是Java端的加密解密";
        String encryptstr = aesEncrypt(origin);
        System.out.println(encryptstr);
        String decryptstr = aesDecrypt(encryptstr);
        System.out.println(decryptstr);

    }


}

就 先 说 到 这 \color{#008B8B}{ 就先说到这}
在 下 A p o l l o \color{#008B8B}{在下Apollo} Apollo
一 个 爱 分 享 J a v a 、 生 活 的 小 人 物 , \color{#008B8B}{一个爱分享Java、生活的小人物,} Java
咱 们 来 日 方 长 , 有 缘 江 湖 再 见 , 告 辞 ! \color{#008B8B}{咱们来日方长,有缘江湖再见,告辞!}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pang_ping/article/details/110818088

智能推荐

Drawing Our First Triangle(绘制第一个三角形)_绘制三角形计算机图形学_萌谷王的博客-程序员宅基地

周一到周五,每天一篇,北京时间早上7点准时更新~,中英文对照,一边学编程一边弹吉他,做一个奇葩码农!请不要怀疑翻译是否有问题,我们的翻译工程师是蓝翔毕业的呢!Drawing a single point is not really that impressive (even if it is really big!)(画个点还不是那么杀改(过瘾的意思,湘西土家族方言))—we alread..._绘制三角形计算机图形学

跨链技术的分析和思考_weixin_34004750的博客-程序员宅基地

2019独角兽企业重金招聘Python工程师标准>>> ..._跨链ccf论文

Oracle归档日志删除_weixin_34167819的博客-程序员宅基地

为什么80%的码农都做不了架构师?>>> ...

第16章 使用Squid部署代理缓存服务_squid 缓存图片_Englandskies的博客-程序员宅基地

16.1代理缓存服务Squid服务程序具有配置简单、效率高、功能丰富等特点,它能支持HTTP、FTP、SSL等多种协议的数据缓存,可以基于访问控制列表(ACL)和访问权限列表(ARL)执行内容过滤与权限管理功能,还可以基于多种条件禁止用户访问存在威胁或不适宜的网站资源,因此可以保护企业内网的安全,提升用户的网络体验,帮助节省网络带宽。在使用Squid服务程序为用户提供缓存代理服务时,具有正向..._squid 缓存图片

在centos7上部署k8s时报“Unable to establish SSL connection.“错误解决方法_centos unable to establish ssl connection._liudeke的博客-程序员宅基地

在centos7上部署k8s时报"Unable to establish SSL connection."错误解决方法这是因为raw.githubusercontent.com这个域名被污染,不能被正常访问。解决办法:在https://www.ipaddress.com/查询域名所解析出的IP把域名和解析出来的IP添加到/etc/hosts文件发现解析出来的IP只有最后一个能正常使用..._centos unable to establish ssl connection.

Qt 无法导入 QSound 头文件_qt10.0.2找不到qsound_Goallegoal的博客-程序员宅基地

Qt 无法导入 QSound 头文件向代码中添加音效时,需要使用到QSound类,就要引入QSound的头文件#include <QSound>但是在实际引入时,发现即使添加了该头文件,还是提示QSound文件不存在,这该如何解决呢?解决方案:首先查看Qt中的帮助文档,找到有关QSound的帮助信息,确认头文件的引入方式正确;然后看到关于qmake的信息:qmake: QT += multimedia,这条信息的含义是,如果想使用QSound需要在.pro文件中加入这条指令。这样就可_qt10.0.2找不到qsound

随便推点

startx 及xinit 介绍_startx 2.3_轻飘风扬的博客-程序员宅基地

1 xinit在说明startx之前,我想我们应该先了解一下xinit。因为startx就是通过调用xinit启动X的。1.1 功能当我们安装了Ubuntu后,默认就已经安装了xinit,它位于/usr/bin下。xinit是一个二进制文件,并非是一个脚本。它的主要功能是启动一个X服务器,同时启动一个基于X的应用程序。1.2 用法xinit的用法为:xinit [[clie_startx 2.3

【编解码】FFmpeg + SDL 的视频播放_ffmpeg sdl视频播放_@hongZ的博客-程序员宅基地

参考:《基于 FFmpeg + SDL 的视频播放器的制作》课程的视频视频文件组成:FFmpeg解码流程(代码):SDL视频显示流程(代码):资料备份:https://download.csdn.net/download/qq_39797956/56354155_ffmpeg sdl视频播放

DVWA的安装与配置教程_32位dvwa_im-Miclelson的博客-程序员宅基地

关于DVWA的安装 配置过程dvwa的安装配置过程完成安装需要准备以下:php study软件下载链接 64位:http://public.xp.cn/upgrades/phpStudy_64.7z ~ 32位http://public.xp.cn/upgrades/phpStudy_32.7zDVWA压缩包 下载链接: https://github.com/ethicalhack3r/..._32位dvwa

window下使用vs2019编译ZLMediaKit,并测试推拉流_zlmediakit vs2019_白杨攻城狮的博客-程序员宅基地

下好相关的依赖库和编译工具1.openssl:本人使用的版本:Win64OpenSSL-3_0_2.exe下载地址:Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com)2.ffmpeg可执行文件本人使用的版本:ffmpeg-2022-04-03-git-1291568c98-essentials_build.7z下载地址:Builds - CODEX FFMPEG _zlmediakit vs2019

electron教程【9】electron通过node-ffi调用c++ dll时候路径问题_ffi 126_jigetage的博客-程序员宅基地

背景:在electron运行目录下新建res子目录,并将所有dll放置在res子目录中,此时通过node-ffi模块调用dll时候,即便是寻找路径写对,还是会出现win32 126的错误。在这里说明一下, 126的错误就是找不到对应模块。原因分析:由于electron程序在运行时会自动寻找所依赖的dll,寻找目录是同级目录,所以会出现上述问题。解决方案:直接将所有依赖的dll放置在运行目录..._ffi 126

由浅入深:基于 Laravel Broadcast 实现 WebSocket C/S 实时通信_xinzi11243094的博客-程序员宅基地

Laravel 集成众多开包即用的功能, 虽然它真的很”胖”, 但这并不影响它是个好框架。本篇文章将采用 Laravel 5.6 版本由浅入深为大家演示: 如何使用内置的 Broadcast(广播)功能实现与客户端实时通信。0x00 准备广播系统用户认证事件系统队列系统前端指南tlaverdure/laravel-echo-server没错,这是你需要的知识储备。因为 PHP 本身并不支持 Web...

推荐文章

热门文章

相关标签