JavaScript + GO 通过 AES + RSA 进行数据加解密

这篇具有很好参考价值的文章主要介绍了JavaScript + GO 通过 AES + RSA 进行数据加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

浏览器端搞些小儿科的加密,就好比在黑暗夜空中,点缀了几颗星星,告诉黑客「这里有宝贵信息,快来翻牌」

JavaScript + GO 通过 AES + RSA 进行数据加解密

浏览器端的加密,都是相对安全的。

它的具体安危,取决于里面存在的信息价值,是否值得破解者出手一试。

就跟那个经典的笑话一样:

某个客户自己开发了一套软件,并买了一个防破解插件,让大牛测试破解难度。

三天后大牛郁闷地说这还挺难搞的,居然花了 3 天。

仔细一看原来是把人家的防破解插件给破了……

一、信息对齐

其实 JavaScript + Go 的加解密,真实代码调用很简单。

我和服务端小伙伴对着网上资料,库库一顿操作就搞定了。

JavaScript + GO 通过 AES + RSA 进行数据加解密

所以在进入代码环节之前,我们先对齐同步一些基本信息,避免其他想了解这块知识点的小伙伴,捋不清里面逻辑。

1.1 什么是加解密

所谓「加密」,就是将你的信息,通过「某种处理」,让它变成不可读,被保护不被非法获取。

而「解密」,就是将处理后的信息,再转换成正常人能读懂的信息。

举个栗子,你要去拿货,对方来了一句「天王盖地虎」。

你是不是要接话,来表明你的身份?

JavaScript + GO 通过 AES + RSA 进行数据加解密

“对暗号”,其实就是一种处理信息的方式,你只有回答出对方的问题,才能进一步操作。

1.2 为什么要数据加密

为了「安全」。

为什么安全要括起来,因为没有绝对的安全。

在浏览器端做数据加解密,只能保证:

  1. 传输的数据是经过加密或者编码的,即使有人通过抓包软件抓取数据,也看不懂或者比较难解开

  2. 确保数据没有经过篡改,确认发送者的身份

注意!以上 2 点只能防抓包,不防注入。

意思就是对方通过 JavaScript 脚本注入,替换你原先写的代码。

JavaScript + GO 通过 AES + RSA 进行数据加解密

这样就可以在你加密信息之前,获取到原信息。

1.3 对称加密

所谓「对称加密」,意思就是大家拿到同一把钥匙,对传递的数据进行加解密。

举个栗子,对称加密就像你和朋友买了一个保险柜并配了 2 把一样的钥匙。

每次你找 ta 聊天,你把信写好,丢到保险柜,把保险柜扔给对方。

然后对方拿一样的钥匙,就可以开保险柜,并把他的信也丢到里面仍回给你。

再举个栗子,高中同学 A 和 B 谈恋爱了,但是他们纸条不能直接写情书呀,要不然被发现就哦豁了。

所以他们想了个法子,写纸条的时候,只写数字,比如 108-1,意思就是找某本书的 108 页第 1 个字。

JavaScript + GO 通过 AES + RSA 进行数据加解密

看,他们的钥匙,就是相同的书,这样信息就等同了,对称了。

常见的对称加密算法:DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6 和 AES。

1.4 非对称加密

所谓「非对称加密」,就是 A 生成一对密钥,将公钥给别人,然后私钥自己藏好,别人通过公钥加密信息给 A,A 拿自己的私钥解密。

举个栗子,就是甲方是养蛊的,ta 有一对子母蛊。

甲方会把子蛊给乙方,母蛊留给自己。

这样哪怕子蛊丢了,别人拿子蛊传递信息,也只有甲方才能通过母蛊获取。

这种情况只有甲方才能破解信息,别人都没法理解不同人拿子蛊传递的信息。

JavaScript + GO 通过 AES + RSA 进行数据加解密

所以非对称加密可以用在松鼠党上:我可不管谁拿了子蛊,只要传递信息给我,我就都存起来。

对称加密算法的运行速度比非对称加密算法快,所以需要加密大量的数据时,建议采用对称加密算法,提升加解密速度。

常见的非对称加密算法:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

1.5 哈希(Hash)算法

所谓哈希(Hash)算法,其实就是将信息做一个不可逆的转换,然后将信息存储起来。

举个栗子,小明同学将自己的密码,通过哈希(Hash)算法,存到了数据库里。

这样别人监听了小明登录账号的接口,也没法获取到里面的内容。

又或者别人看到了数据库,也不知道小明同学记录的原始密码是什么。

哈希(Hash)算法中,MD5 因为计算机算力提升,可以快速找到一个 MD5 的值对应的原文,所以大家由 MD5 的使用变成了 SHA-256 的使用,提升了加密的安全性。

JavaScript + GO 通过 AES + RSA 进行数据加解密

当然,如果小伙伴们的密码比较简单,例如 123456 或者 666666 这种,被破解的还是大有可能的,可以在线试试 https://tool.oschina.net/encrypt?type=2

常见的哈希算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1

1.6 数据加密算法的选择

在上面中,我们知道加密算法,大致分为「对称加密」和「非对称加密」以及「哈希(Hash)算法」这 3 种类型。

其中哈希(Hash)算法在对接中不可用了,因为它一般用作存储,不解出来。

而简单的对称加密和非对称加密,可能又过不了安全审查。

所以再三考虑下,我们采用 AES + RSA(对称加密 + 非对称加密)这种加密方式,提高数据传输的安全性。

二、RSA + AES

RSA + AES 的方案,我们采用这种形式:

  1. 服务端生成一堆 RSA 密钥,其中私钥自己保存,公钥下发给浏览器端

  2. 浏览器端通过随机函数,生成 AES 加密需要的 key(下面简称 AES key)

  3. 浏览器端通过 AES 和步骤 2 生成的 key,对要传输的数据进行加密,通过接口的 body 传递

  4. 浏览器端通过 RSA,对自己生成的 AES key 进行加密,通过接口的 header 传递

  5. 服务端拿到数据后,先通过 RSA 解密 header,获取到 AES key,再通过 AES,解密出 body 的数据

JavaScript + GO 通过 AES + RSA 进行数据加解密

2.1 RSA 加解密

这一块的困难点在于 Go,因为 JavaScript 更多用的是一个库,即 jsencrypt

前端的 RSA 加密,是:

  1. 通过 jsencrypt,设置公钥

  2. 加密信息,生成 base64 数据并调用接口,传递给服务端

代码如下:

import JSEncrypt from 'jsencrypt';

const encryptor = new JSEncrypt();

/**
 * @name RSA-设置公钥
 * @param val 公钥
 */
export const setPublicKey = (val: string) => {
  encryptor.setPublicKey(val);
}

/**
 * @name RSA-加密
 * @param data 待加密数据
 * @returns {PromiseLike<ArrayBuffer>} 返回加密字符串
 */
export const rsaEncrypt = (data: string) => {
  return encryptor.encrypt(data) || '';
}

服务端的 RSA 解密,是:

  1. 先解密 base64

  2. 再通过 RSA 解密

Go 的代码可参考:

  • 《CSDN - 在vue、golang搭建的前后端系统中使用jsencrypt包实现RSA加解密功能》https://blog.csdn.net/sinat_26553595/article/details/122411287

  • 《语言中文网 - 前后端交互,密码加密,RSA 实现前端 js 加密,后端 go 解密》https://studygolang.com/articles/35387

因为 Go 这边的库可能比较原始,所以如果碰到问题的话,大概率可能是公私钥的生成有问题,它需要按照最原始的标准格式来生成。

2.2 AES 加解密

对这一块确实没啥经验,网上说的文章,要么单独讲 JavaScript 的,要么单独讲 Go 的,整个人看完都懵圈。

好在网上大佬也确实给力,我跟服务端大佬合计了下,将一些点给撇掉了,直接采用:

  • 《思否 - Golang 实现与 crypto-js 一致的 AES 简单加解密》https://segmentfault.com/a/1190000043754783

实际开发中使用 AES 加密解密需要注意的地方:

  • 服务端和我们客户端必须使用一样的密钥和初始向量 IV

  • 服务端和我们客户端必须使用一样的加密模式

  • 服务端和我们客户端必须使用一样的 Padding 模式

首先,上面说这些可能有所信息误导,所以咱们直接看前端通过 JavaScript 生成 AES key 及加解密方法:

// 为什么不直接用 window.crypto,因为这个库做了兼容,可以看 https://github.com/brix/crypto-js/blob/4dcaa7afd08f48cd285463b8f9499cdb242605fa/src/core.js#L13
import CryptoJS from 'crypto-js';

/**
 * @name AESKey
 * @description 生成 AES Key
 * @return 随机生成 16 位的 AES Key
 */
export const createAesKey = () => {
  const expect = 16;
  let str = Math.random().toString(36).substr(2);
  while (str.length < expect) {
    str += Math.random().toString(36).substr(2);
  }
  str = str.substr(0, 16);
  return str;
}

/**
 * @name AES-加密
 * @param raw 待加密字段
 * @param AESKey AES Key
 * @return {string} 返回加密字段
 */
export const aesEncrypt = (raw: any, AESKey: string) => {
  const cypherKey = CryptoJS.enc.Utf8.parse(AESKey);
  CryptoJS.pad.ZeroPadding.pad(cypherKey, 4);

  const iv = CryptoJS.SHA256(AESKey).toString();
  const cfg = { iv: CryptoJS.enc.Utf8.parse(iv) };
  return CryptoJS.AES.encrypt(raw, cypherKey, cfg).toString();
}

/**
 * @name AES-解密
 * @param raw 待解密数据
 * @param AESKey 解密 key
 * @returns {string} 返回解密字符串
 */
export const aesDecrypt = (raw: string, AESKey: string) => {
  const cypherKey = CryptoJS.enc.Utf8.parse(AESKey);
  CryptoJS.pad.ZeroPadding.pad(cypherKey, 4);

  const iv = CryptoJS.SHA256(AESKey).toString();
  const cfg = { iv: CryptoJS.enc.Utf8.parse(iv) };

  const decrypt = CryptoJS.AES.decrypt(raw, cypherKey, cfg);
  return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

然后,在上面这段代码,有几个关键信息指标需要统一:

  • mode:AES 有各种加密模式,例如 CBC、CFB、CTR 等模式,在前端的 crypto-js 说明文档里面可以看到它含有 6 种

JavaScript + GO 通过 AES + RSA 进行数据加解密

  • iv:AES 在一些加密模式上,需要指定 IV,即初始向量

  • padding:AES 需要加密的数据,不是 16 的倍数的时候,需要对原本的数据做 padding 操作(即补全长度到固定的位数),它有 Pkcs7、AnsiX923 等种类

JavaScript + GO 通过 AES + RSA 进行数据加解密

最后,服务端 Go 的代码可以参考:

package main

import (
  "fmt"

  "github.com/LinkinStars/go-scaffold/contrib/cryptor"
)

func main() {
  key := "1234"

  e := cryptor.AesSimpleEncrypt("Hello World!", key)
  fmt.Println("加密后:", e)
  
  d := cryptor.AesSimpleDecrypt(e, key)
  fmt.Println("解密后:", d)

  iv := cryptor.GenIVFromKey(key)
  fmt.Println("使用的 IV:", iv)
}

// 输出
// 加密后:NHlpzbcTvOj686VaF7fU7g==
// 解密后:Hello World!
// 使用的 IV: 03ac674216f3e15c

参考文献

搜索关键词:浏览器端 rsa + aes

  • 《博客园 - 常用加密算法概述》https://www.cnblogs.com/colife/p/5566789.html

  • 《CSDN - 浅谈常见的七种加密算法及实现》https://blog.csdn.net/baidu_22254181/article/details/82594072

  • 《简书 - 一、消息摘要算法MD5、SHA-1》https://www.jianshu.com/p/38c93c677124

  • 《简书 - sha256为什么不可逆,sha256的安全性如何》https://www.jianshu.com/p/fb2cc870337a

  • 《CSDN - 网络传输数据加解密方案选择(RSA+AES)》https://blog.csdn.net/yuzhiqiang_1993/article/details/88641265

  • 《掘金 - 实习技术总结(八)前端AES解密》https://juejin.cn/post/7122392902319210503

  • 《CSDN - 网络传输数据加解密方案选择(RSA+AES)》https://blog.csdn.net/yuzhiqiang_1993/article/details/88641265

  • 《KACIRAS - WebCrypto 与 Node 的 AES-GCM 踩坑》https://blog.kaciras.com/article/26/aes-crypto-in-node-and-browser

  • 《掘金 - 前端利用jsencrypt.js进行RSA加密》https://juejin.cn/post/7075542251228626951

  • 《思否 - 一套简单的基于 RSA + AES 加密机制的前端解决方案》https://segmentfault.com/a/1190000019399444

  • 《掘金 - 前端加解密方案探讨》https://juejin.cn/post/6844903745701019662

  • 《掘金 - springboot+vue接口加密:RSA+AES》https://juejin.cn/post/7181726644799963173

  • 《思否 - Golang 实现与 crypto-js 一致的 AES 简单加解密》https://segmentfault.com/a/1190000043754783

  • 《阿里云 - RSA:jsencrypt/Python实现加密》https://developer.aliyun.com/article/813627

  • 《简书 - jsencrypt前台加密,Go后台解密失败》https://www.jianshu.com/p/f2b03fe16193

  • 《CSDN - 在vue、golang搭建的前后端系统中使用jsencrypt包实现RSA加解密功能》https://blog.csdn.net/sinat_26553595/article/details/122411287

  • 《语言中文网 - 前后端交互,密码加密,RSA 实现前端 js 加密,后端 go 解密》https://studygolang.com/articles/35387


不折腾的前端,和咸鱼有什么区别!

觉得文章不错的小伙伴欢迎点赞/点 Star。

如果小伙伴需要联系 jsliang

  • Github

  • 掘金

个人联系方式存放在 Github 首页,欢迎一起折腾~

争取打造自己成为一个充满探索欲,喜欢折腾,乐于扩展自己知识面的终身学习斜杠程序员。

jsliang 的文档库由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。
基于 https://github.com/LiangJunrong/document-library 上的作品创作。
本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。文章来源地址https://www.toymoban.com/news/detail-631990.html

到了这里,关于JavaScript + GO 通过 AES + RSA 进行数据加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RSA加密解密(无数据大小限制,php、go、java互通实现)

    RSA加解密中必须考虑到的**长度、明文长度和密文长度问题。明文长度需要小于**长度,而密文长度则等于**长度。因此当加密内容长度大于**长度时,有效的RSA加解密就需要对内容进行分段。 这是因为,RSA算法本身要求加密内容也就是明文长度m必须0m**长度n。如果小于这个长

    2024年02月15日
    浏览(75)
  • python实现rsa\aes\sm2\sm4加解密

    相关依赖: gmssl==3.2.2 pycryptodome == 3.9.7 基类: Rsa分段加解密实现(适用于pkcs1/8格式的2048bit私钥): AES加解密: SM2加解密: SM4加解密: 利用枚举扩展: 使用:

    2024年02月16日
    浏览(34)
  • 用java语言写一个AES算法,使用AES(CBC模式)对数据进行加密或解密。加解密用到的密钥(Key)和密钥偏移量(IV),代码实例类编写。

    以下是一个使用Java编写的AES算法实例,使用AES(CBC模式)对数据进行加密和解密。代码中包括了生成随机密钥和密钥偏移量的方法。 java Copy code import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; import

    2024年02月07日
    浏览(61)
  • go语言使用AES加密解密

    Go语言提供了标准库中的crypto/aes包来支持AES加密和解密。下面是使用AES-128-CBC模式加密和解密的示例代码:

    2024年02月06日
    浏览(72)
  • JAVA+Node/JavaScript 前后端通讯 RSA 加解密实现

    实际项目中,前后端或跨语言加密通讯的场景十分常见。这里以 Java 和 Node.js (兼容 浏览器 )两种开发语言为例,实现 RSA 加解密通讯。 此代码采用分段加解密,理论上支持无限长度的文本内容 使用示例:

    2024年02月07日
    浏览(48)
  • RSAUtil 前端 JavaScript JSEncrypt 实现 RSA (长文本)加密解密

    文章归档:https://www.yuque.com/u27599042/coding_star/cl4dl599pdmtllw1 import JSEncrypt from ‘jsencrypt’ import {stringIsNull} from “@/utils/string_utils.js”:https://www.yuque.com/u27599042/coding_star/slncupw7un3ce7cb import {isNumber} from “@/utils/number_utils.js”:https://www.yuque.com/u27599042/coding_star/tuwmm3ghf5lgo4bw 注意: 此方

    2024年04月22日
    浏览(69)
  • Python对AES进行加密和解密的多种方法

    前言 本文是该专栏的第24篇,后面会持续分享python的各种干货知识,值得关注。 做过爬虫项目的同学,对AES加解密都有遇到过。 在密码学中,加密算法也分为双向加密和单向加密。单向加密包括MD5、SHA等摘要算法,它们是不可逆的。而双向加密包括 对称加密 和 非对称加密

    2023年04月14日
    浏览(37)
  • 用RSA进行加解密和数字签名

    1.选择一对素数p,q 2.n=p*q 3.φ(n)=(n-1)(q-1) 4.找e(加密秘钥encrypt),使e与φ(n)互质且 1eφ(n) 5.计算d(解密密钥decrypt),d * e ≡ 1 mod φ(n), ≡为互余符号,即 (d * e) mod φ(n)= 1 6.公钥(e,n) 私钥(d,n) 7.设明文m,密文c,明文加密,密文c = m^e mod n 8.密文解密,明文m = c^d mod n 例:e=3 p=5 q=11 m=1

    2024年02月10日
    浏览(37)
  • 使用 crypto-js 进行 AES 加解密操作

    在前端开发中,数据的加密和解密是为了保障用户隐私和数据的安全性而常见的任务。 AES (Advanced Encryption Standard)是一种对称密钥加密算法,被广泛用于保护敏感信息的传输和存储。本文将介绍 AES 加解密的基本原理,并结合 Crypto-JS 库提供的实例代码进行说明。 AES 是一种

    2024年01月19日
    浏览(40)
  • RSA-CRT 使用中国剩余定理CRT对RSA算法进行解密

    使用中国剩余定理对RSA进行解密,可以提高RSA算法解密的速度。 有关数论的一些基础知识可以参考以下文章: 密码学基础知识-数论(从入门到放弃) 设p和q是不同的质数,且n = p*q。对于任意(X1, x2),其中 0 ≤ x1 p 和 0 ≤ x2 q,存在数x,其中 0 ≤ x n。 中国剩余定理给出了以下的

    2024年02月04日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包