当前位置: 代码网 > it编程>前端脚本>Golang > 用go语言实现WebAssembly数据加密的示例讲解

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

2024年05月18日 Golang 我要评论
一、背景和意义在web开发中,有时候为了提升安全性需要对数据进行加密。由于js代码相对比较易读,直接在js中做加密安全性较低,而webassembly代码不如js易读,使用webassemply做数据

一、背景和意义

在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会标红:

接下来执行如下命令生成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="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数据加密内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com