angular实现国密算法sm2、sm3和sm4的ts版,基于sm-crypto库实现,前后端实现

ts版,js的话直接根据npm文档调用就可以了!

ts提供的方法有问题,所以还换了个思路来实现!而且因为不是nodeJs环境所以const sm4 = require('sm-crypto').sm4这个在ts里是报错的导致无法实现,如果是使用的是electron那么使用const sm4 = window.require('sm-crypto').sm4就可以来调用js里的方法了。

npm文档:sm-crypto

前提:方法入口出口都是通过ts的Buffer来传递的也就是字节数组Uint8Array,并且前端加解密后端可以对应加解密

导入库

# js库
npm install sm-crypto --save
#下载ts实现的一个文件index.d.ts
npm install @types/sm-crypto --save

index.d.ts文件内容如下:

遇到的问题1:sm4算法直接使用的话会遇到问题,前端加密后去后端解密解出来的不一致,它实现的时候目前猜测的是传入的参数options与后端不一致,因为不可以修改所以放弃,直接去调用底层js来实现。

在这里插入图片描述

这是js提供出来的方法,以及实现加解密的方法,所以我们可以看到options是能自己修改的,我们就来自定义实现。

module.exports = {encrypt(inArray, key, options) {return sm4(inArray, key, 1, options)},decrypt(inArray, key, options) {return sm4(inArray, key, 0, options)}
}
function sm4(inArray, key, cryptFlag, {padding = 'pkcs#5', mode, output = 'string'} = {}) {if (mode === CBC) {// @TODO,CBC 模式,默认走 ECB 模式}// 检查 keyif (typeof key === 'string') key = hexToArray(key)if (key.length !== (128 / 8)) {// key 不是 128 比特throw new Error('key is invalid')}// 检查输入if (typeof inArray === 'string') {if (cryptFlag !== DECRYPT) {// 加密,输入为 utf8 串inArray = utf8ToArray(inArray)} else {// 解密,输入为 16 进制串inArray = hexToArray(inArray)}} else {inArray = [...inArray]}// 新增填充if (padding === 'pkcs#5' && cryptFlag !== DECRYPT) {const paddingCount = BLOCK - inArray.length % BLOCKfor (let i = 0; i < paddingCount; i++) inArray.push(paddingCount)}// 生成轮密钥const roundKey = new Array(ROUND)sms4KeyExt(key, roundKey, cryptFlag)const outArray = []let restLen = inArray.lengthlet point = 0while (restLen >= BLOCK) {const input = inArray.slice(point, point + 16)const output = new Array(16)sms4Crypt(input, output, roundKey)for (let i = 0; i < BLOCK; i++) {outArray[point + i] = output[i]}restLen -= BLOCKpoint += BLOCK}// 去除填充if (padding === 'pkcs#5' && cryptFlag === DECRYPT) {const paddingCount = outArray[outArray.length - 1]outArray.splice(outArray.length - paddingCount, paddingCount)}// 调整输出if (output !== 'array') {if (cryptFlag !== DECRYPT) {// 加密,输出转 16 进制串return ArrayToHex(outArray)} else {// 解密,输出转 utf8 串return arrayToUtf8(outArray)}} else {return outArray}
}

一:实现SM4

这里我是根据他js提供出来方法的思路来实现的,因为我对js也不熟悉,没怎么写过,一开始是打算用类似工具类的思路来实现,发现那样实现不能使用const sm4 = require('sm-crypto').sm4;,所以只能换思路了。

下面一定要用module.exports,一开始我用的exports会报错的。底层js里也是使用的module.exports,目前区别可以百度下。

options:{padding: ‘pkcs#5’, output: ‘array’} 我传递的这个padding和mode可以和后端来协调不一致可以修改,mode默认ECB,这里ECB和CBC无区别js给过滤了可以看源码,输出都是array,因为我需要的是字节数组,如果想要string也可以改成string,具体可以自己看下源码里面的实现,很简单!

const sm4 = require('sm-crypto').sm4;function encodeBySM4(buf, key) {return sm4.encrypt(buf, key, {padding: 'pkcs#5', output: 'array'});
}function decodeBySM4(buf, key) {return sm4.decrypt(buf, key, {padding: 'pkcs#5', output: 'array'});
}module.exports = {encodeBySM4, decodeBySM4
};

接下来使用ts调用它

import {Buffer} from 'buffer';
//引入js
import * as sm4 from 'src/assets/lib/SM4Execport';
export class SM4Utils {/*** @param buf 字节数组* @param key key** 传入字节数组和key,返回加密后的字节数组*/public static encrypt(buf: Buffer, key: string): Buffer {return sm4.encodeBySM4(buf, key);}public static decrypt(buf: Buffer, key: string): Buffer {return sm4.decodeBySM4(buf, key);}
}

测试

<button style="background-color: yellow;" (click)="enTest()">加密解密</button>
  enTest() {let buffer = SM4Utils.encrypt(new Buffer([96,22]),"0123456789abcdeffedcba9876543210");console.log(buffer);let buffer1 = SM4Utils.decrypt(buffer,"0123456789abcdeffedcba9876543210");console.log(buffer1);}

在这里插入图片描述

二:实现SM2

这里SM2不管是ts还是js输入输出都是string,加密输入utf8的String,输出hex字符串,解密输入hex字符串,输出utf8字符串,这样的话就是只能加密字符流,如果是字节流的话就转换出错了,例如[22,33,44,55],对他转为utf8去加密,会转成3字节一个所以是两个字符,可能是两个乱码,也可能是一个中文一个乱码。解密后会转成6字节。所以在加密前加了一层base64或者加hex也可以。解密后再解一层base64。如果只对字符串操作直接加解密就可以。

这里面还有个带不带04的问题,后端的库里和前端的库有点区别,后面再说!

import {sm2} from 'sm-crypto';
import {Buffer} from "buffer";export class SM2Utils {public static getKeysPairHex(){let keysPairHex = sm2.generateKeyPairHex();let publicKey = keysPairHex.publicKey;let privateKey = keysPairHex.privateKey;return {publicKey, privateKey};}//原始数据 ==> base64 ==> 对base字符串sm2加密后的bufferpublic static encrypt(buffer: Buffer,publicKey:string): Buffer {let hexStr = buffer.toString("base64");  //将buffer转成base进制return new Buffer("04"+sm2.doEncrypt(hexStr, publicKey, 1),'hex');//加密出来是hex,将它转为byte[]}//buffer ⇒  hexstr ⇒ base64 ⇒ 原始数据public static decrypt(buffer: Buffer,privateKey:string): Buffer {let strHex = buffer.toString('hex');strHex = strHex.substr(2);let str = sm2.doDecrypt(strHex, privateKey, 1);return new Buffer(str,'base64');}}

04问题

后端加密出来的数据头部相比前端多了04,因为前端底层将04去掉了

在这里插入图片描述

这里进行substr了,后端加密出来的数据是130位,前端128位,比前端多了个04

在这里插入图片描述

前端sm2加解密分别处理了这个问题:
"04"+sm2.doEncrypt(hexStr, publicKey, 1)//加密后的hex加上04
strHex = strHex.substr(2);//解密钱去掉04

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

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

相关文章

【转】.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)

很久没有写博客了&#xff0c;今年做的产品公司这两天刚刚开了发布会&#xff0c;稍微清闲下来&#xff0c;想想我们做的产品还有没有性能优化空间&#xff0c;于是想到了.Net的异步可以优化性能&#xff0c;但到底能够提升多大的比例呢&#xff1f;恰好有一个朋友正在做各种语…

win7关机快捷键_电脑快捷键大全(上)

Windows快捷键1单独按Windows&#xff1a;显示或隐藏“开始”功能表WindowsBREAK&#xff1a;显示“系统属性“对话框WindowsD显示桌面或回复桌面Windows M最小化所有窗口WindowsShiftM&#xff1a;还原最小化的窗口CrtlShiftN:新建文件夹WindowsE&#xff1a;打开“我的电脑”…

【转】ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET

以下为教程: 在现有webapi项目中,nuget安装以下两个插件 swagger.net.ui swashbuckle 安装完毕后可以卸载Swagger.NET,此处不需要! 安装完毕后屏蔽以下代码 直接运行调试 在浏览器的目录后面加上/swagger即可跳转到swagger调试页 此时如果没有注释. 项目属性里添加xml注释…

idea提示“ cannot access xxxxxxxx.class“的解决方法,idea的bug

同一个包下的public类使用报错&#xff0c;应该是idea的bug&#xff1a; file -> Invalidate Caches / Restart

电脑屏保在哪里设置_手机屏保调成绿色能护眼?真的吗?

说到护眼&#xff0c;你首先想到的是什么颜色&#xff1f;估计90%的人都会不自觉的想到绿色&#xff01;因为从小家长和老师都会跟我们说&#xff1a;眼睛累了就多看窗户外的绿色植物。久而久之&#xff0c;一说到护眼&#xff0c;大家脑海里第一个想到的就是绿色。你会看到不少…

电脑休眠和睡眠的区别_关机、睡眠、休眠的区别

都知道电脑有关机、睡眠、休眠三种休息模式&#xff0c;但是后两个选项使用的人非常少&#xff0c;大多数人每次用完电脑都会选择立即「关机」。有人是为了让电脑「休息」&#xff0c;有人是为了低碳精神&#xff0c;还有人是因为下班不关电脑要罚款&#xff0c;不管是什么原因…

SpringCloud:学习Docker安装zookeeper,注册服务

1.没镜像就拉取镜像 dockerhub中查看版本 官网 docker pull zookeeper:3.4.14 不加版本号也行&#xff0c;默认拉取最新版 创建并启动容器 docker run -p 2181:2181 --privilegedtrue --name zookeeper01 -d zookeeper –privilegedtrue 容器内用户开启root权限 docker ps…

win10固态硬盘分区 整数_惠普HP笔记本Win10改Win7系统教程

惠普HP笔记本和台式机目前都预装的Win10系统&#xff0c;当然Win7旗舰版才是很多用户喜欢的&#xff0c;不过换装Win7有很多方面比较麻烦&#xff0c;如BIOS设置、U盘启动及方分方面都是很多用户不熟悉的&#xff0c;这里小编就详细分享下惠普笔记本Win10改Win7系统教程(BIOS设…

SpringCloud:学习 Docker安装Consul,注册服务

1.拉取镜像 docker pull consul 2.启动容器 docker run -d -p 8500:8500 --restartalways --nameconsul consul:latest agent -server -bootstrap -ui -node1 -client0.0.0.0 创建容器时没有添加参数 --restartalways &#xff0c;导致的后果是&#xff1a;当 Docker 重启时…

【转】WebApi 身份认证解决方案:Basic基础认证

参考路径&#xff1a;https://www.cnblogs.com/landeanfen/p/5287064.html 前言&#xff1a;最近&#xff0c;讨论到数据库安全的问题&#xff0c;于是就引出了WebApi服务没有加任何验证的问题。也就是说&#xff0c;任何人只要知道了接口的url&#xff0c;都能够模拟http请求去…

LeetCode每日打卡 - 汉明距离

位异或运算&#xff08;^&#xff09; 运算规则是&#xff1a;两个数转为二进制&#xff0c;然后从高位开始比较&#xff0c;如果相同则为0&#xff0c;不相同则为1。 比如&#xff1a;8^11. 8转为二进制是1000&#xff0c;11转为二进制是1011.从高位开始比较得到的是&#xff…

【转】Task和async/await详解

一、什么是异步 同步和异步主要用于修饰方法。当一个方法被调用时&#xff0c;调用者需要等待该方法执行完毕并返回才能继续执行&#xff0c;我们称这个方法是同步方法&#xff1b;当一个方法被调用时立即返回&#xff0c;并获取一个线程执行该方法内部的业务&#xff0c;调用者…

LeetCode每日打卡 - 反转每对括号间的子串

题解中有个更好的思路&#xff0c;stack存入的不是(的坐标&#xff0c;存入每次到左括号的字符串&#xff0c;拿到右括号就对其进行反转&#xff0c;更妙一些。 import java.util.Stack; class Solution {public String reverseParentheses(String s) {Stack<Integer> s…

iar stm32_树莓派玩转STM32开发(一)——介绍篇

01—树莓派树莓派(Raspberry Pi)听起来让人流口水&#xff0c;但它的确不是吃的(身为非吃货的我第一次也以为它是食物……)。树莓派是基于ARM架构的Linux卡片电脑&#xff0c;由英国树莓派基金会开发&#xff0c;目的是以低价硬件以及自由软件来促进学校的基本电脑科学教育。树…

JavaScript面向对象的理解

前言 1. 本文默认阅读者已有面向对象的开发思想&#xff0c;最好是使用过c、java&#xff0c;本人Java不太熟悉&#xff0c;所以例子都是用C来写的。 2. 本人不是专业网站开发人员&#xff0c;接触javascript一年多&#xff0c;自己也编写调试了一些代码&#xff0c;本文完全根…

【转】C# 彻底搞懂async/await

关键&#xff1a; 异步方法&#xff1a;在执行完成前立即返回调用方法&#xff0c;在调用方法继续执行的过程中完成任务。 async/await 结构可分成三部分&#xff1a; &#xff08;1&#xff09;调用方法&#xff1a;该方法调用异步方法&#xff0c;然后在异步方法执行其任务的…

LeetCode每日打卡 - 汉明距离总和

有点慢&#xff0c;两层循环也可以完成&#xff0c;就是换个方向&#xff0c;外层遍历32大小的bits数组&#xff0c;里层遍历nums的数字每次右移一位&#xff0c;计算方法类似。 class Solution {public int totalHammingDistance(int[] nums) {//int 是4byte &#xff0c; 每…

python编写代码_用 Python 编写干净、可测试、高质量的代码

用 Python 编写干净、可测试、高质量的代码Noah Gift 2010 年 12 月 20 日发布简介 编写软件是人所承担的最复杂的任务之一。AWK 编程语言和 "K and R C" 的作者之一 Brian Kernigan 在 Software Tools 一书中总结了软件开发的真实性质&#xff0c;他说&#xff0c;“…

阿里云服务器被[kthreaddi]挖矿病毒攻击

首先我根本https://blog.csdn.net/weixin_41599103/article/details/115403332这个博客试了下并没有成功&#xff0c;所以应该是被侵入的程序不一样 先去阿里云里看一下详情 明确告诉了是通过docker被攻击了&#xff0c;先将wordpress容器停止并删除容器和镜像 kill掉进行&am…

python canvas画弧度_python画一朵玫瑰给你

听说 python 还能画画&#xff1f;是的&#xff0c;今天亲手画一朵玫瑰给你。turtle 是 python 中一个强大的绘制图像的库&#xff0c;可以用来绘制各种图像&#xff0c;使用起来很方便。但是需要计算各种角度、距离等&#xff0c;所以要想完成一幅复杂的图像还是有一定的难度的…