脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - 用go语言实现WebAssembly数据加密的示例讲解

用go语言实现WebAssembly数据加密的示例讲解

2024-03-19 15:07qinyuan15   Golang

在Web开发中,有时候为了提升安全性需要对数据进行加密,由于js代码相对比较易读,直接在js中做加密安全性较低,而WebAssembly代码不如js易读,本文提供一个用go语言实现的WebAssembly数据加密示例,需要的朋友可以参考下

一、背景和意义

在Web开发中,有时候为了提升安全性需要对数据进行加密。由于js代码相对比较易读,直接在js中做加密安全性较低,而WebAssembly代码不如js易读,使用WebAssemply做数据加密对安全性有一定的提升(不过熟悉WebAssembly的人还是能看懂加解密过程)。本文提供一个用go语言实现的WebAssembly数据加密示例。

二、创建WebAssembly文件

创建一个空目录,执行如下命令初始化go模块:

go mod init wasm-demo

接下来在当前目录下创建main.go文件,提供数据加密与解密的方法:

package main

import (
   "bytes"
   "crypto/aes"
   "crypto/cipher"
   "encoding/hex"
   "fmt"
   "syscall/js"
)

var aesCode = "0000000000000000" // 作为demo,这里只用16个0作为密钥

// pkcs5Padding 对数据进行填充,使其长度为块大小的倍数。
func pkcs5Padding(cipherText []byte, blockSize int) []byte {
   padding := blockSize - len(cipherText)%blockSize
   padText := bytes.Repeat([]byte{byte(padding)}, padding)
   return append(cipherText, padText...)
}

// pkcs5UnPadding 移除填充数据。
func pkcs5UnPadding(decrypted []byte) []byte {
   length := len(decrypted)
   unPadding := int(decrypted[length-1])
   return decrypted[:(length - unPadding)]
}

// aesDecrypt 加密
func aesEncrypt(encryptStr string) (string, error) {
   encryptBytes := []byte(encryptStr)
   block, err := aes.NewCipher([]byte(aesCode))
   if err != nil {
      return "", err
   }

   blockSize := block.BlockSize()
   encryptBytes = pkcs5Padding(encryptBytes, blockSize)

   blockMode := cipher.NewCBCEncrypter(block, []byte(aesCode)[:blockSize])
   encrypted := make([]byte, len(encryptBytes))
   blockMode.CryptBlocks(encrypted, encryptBytes)
   return hex.EncodeToString(encrypted), nil
}

// aesDecrypt 解密
func aesDecrypt(decryptStr string) (string, error) {
   decryptBytes, err := hex.DecodeString(decryptStr)
   if err != nil {
      return "", err
   }

   block, err := aes.NewCipher([]byte(aesCode))
   if err != nil {
      return "", err
   }

   blockMode := cipher.NewCBCDecrypter(block, []byte(aesCode)[:block.BlockSize()])
   decrypted := make([]byte, len(decryptBytes))

   blockMode.CryptBlocks(decrypted, decryptBytes)
   decrypted = pkcs5UnPadding(decrypted)
   return string(decrypted), nil
}

func jsFunc(handler func(string) (string, error)) js.Func {
   return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
      var result string
      var err error
      if len(args) > 0 {
         result, err = handler(args[0].String())
      }
      return js.ValueOf(map[string]interface{}{
         "result": result,
         "err":    err,
      })
   })
}

func main() {
   fmt.Println("Go wasm loaded!")
   js.Global().Set("aesEncrypt", jsFunc(aesEncrypt))
   js.Global().Set("aesDecrypt", jsFunc(aesDecrypt))
   <-make(chan bool)
}

如果是在goland中编辑此代码,需要在Settings中设置一下Build Tags,将OS设置为js,Arch设置为wasm,否则代码编辑器里的syscall/js会标红:

用go语言实现WebAssembly数据加密的示例讲解

接下来执行如下命令生成wasm文件main.wasm:

GOOS=js GOARCH=wasm go build -o main.wasm

三、在前端页面中使用WebAssemply的加解密方法

执行如下命令将go目录下的wasm_exec.js复制过来到当前目录:

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

接下来创建前端代码index.html文件:

<!DOCTYPE html>
<html lang="utf8">
    <head>
        <title>wasm demo</title>
        <script src="https://www.zhanid.com/jiaoben/wasm_exec.js"></script>
        <script>
            const go = new Go();
            WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then(result => {
                go.run(result.instance);
                const encrypt = aesEncrypt("HelloWorld");
                console.log("encrypt result: ", encrypt);
                console.log("decrypt result: ", aesDecrypt(encrypt.result));
            });
        </script>
    </head>
    <body></body>
</html>

将当前目录添加到nginx中,然后通过nginx提供的端口访问index.html,可以看到控制台输出加解密的结果如下:

用go语言实现WebAssembly数据加密的示例讲解

到此这篇关于用go语言实现WebAssembly数据加密的示例讲解的文章就介绍到这了,更多相关go WebAssembly数据加密内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/7346959888008118306

延伸 · 阅读

精彩推荐
  • Golanggolang中make和new的区别示例详解

    golang中make和new的区别示例详解

    Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似。不过解释两者之间的不同也非常容易,下面这篇文章主要介绍了golang中make和new的区...

    sanyuesha5252020-05-08
  • Golang手把手带你走进Go语言之语法基础解析

    手把手带你走进Go语言之语法基础解析

    这篇文章主要介绍了手把手带你走进Go语言之语法基础,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考...

    我是小白呀10942021-09-19
  • GolangGo timer如何调度

    Go timer如何调度

    本篇文章剖析下 Go 定时器的相关内容。定时器不管是业务开发,还是基础架构开发,都是绕不过去的存在,由此可见定时器的重要程度,感兴趣的可以了解...

    haohongfan8842021-08-08
  • Golanggolang常用库之操作数据库的orm框架-gorm基本使用详解

    golang常用库之操作数据库的orm框架-gorm基本使用详解

    这篇文章主要介绍了golang常用库之操作数据库的orm框架-gorm基本使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的...

    九卷5192021-01-26
  • GolangGO语言数组和切片实例详解

    GO语言数组和切片实例详解

    这篇文章主要介绍了GO语言数组和切片的用法,以实例形式较为详细的分析了GO语言中数组与切片的创建及使用技巧,是深入学习GO语言的基础,需要的朋友可以...

    shichen20145282020-04-12
  • GolangGolang教程之不可重入函数的实现方法

    Golang教程之不可重入函数的实现方法

    这篇文章主要给大家介绍了关于Golang教程之不可重入函数的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值...

    HULK一线技术杂谈5932020-05-19
  • GolangGolang中time.After的使用理解与释放问题

    Golang中time.After的使用理解与释放问题

    这篇文章主要给大家介绍了关于Golang中time.After的使用理解与释放问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值...

    90design9242020-05-18
  • GolangGO 使用Webhook 实现github 自动化部署的方法

    GO 使用Webhook 实现github 自动化部署的方法

    这篇文章主要介绍了GO 使用Webhook 实现github 自动化部署的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值...

    周伯通的麦田5552020-07-09