zoukankan      html  css  js  c++  java
  • go AES 加密 和解密

    其实网上关于aes加密和解密的文章很多,尤其是 https://cloud.tencent.com/developer/section/1140748, 只是我个人喜欢用字符串形式,所以整理了一下:

    package utils
    
    import (
        "crypto/aes"
        "crypto/cipher"
        "crypto/rand"
        "encoding/hex"
        "fmt"
        "io"
    )
    
    /*
        AES  CBC 加密
        key:加密key
        plaintext:加密明文
        ciphertext:解密返回字节字符串[ 整型以十六进制方式显示]
    
    */
    func AESCBCEncrypt(key, plaintext string) (ciphertext string) {
        plainbyte := []byte(plaintext)
        keybyte := []byte(key)
        if len(plainbyte)%aes.BlockSize != 0 {
            panic("plaintext is not a multiple of the block size")
        }
        block, err := aes.NewCipher(keybyte)
        if err != nil {
            panic(err)
        }
    
        cipherbyte := make([]byte, aes.BlockSize+len(plainbyte))
        iv := cipherbyte[:aes.BlockSize]
        if _, err := io.ReadFull(rand.Reader, iv); err != nil {
            panic(err)
        }
    
        mode := cipher.NewCBCEncrypter(block, iv)
        mode.CryptBlocks(cipherbyte[aes.BlockSize:], plainbyte)
    
        ciphertext = fmt.Sprintf("%x
    ", cipherbyte)
        return
    }
    
    /*
        AES  CBC 解码
        key:解密key
        ciphertext:加密返回的串
        plaintext:解密后的字符串
    */
    func AESCBCDecrypter(key, ciphertext string) (plaintext string) {
        cipherbyte, _ := hex.DecodeString(ciphertext)
        keybyte := []byte(key)
        block, err := aes.NewCipher(keybyte)
        if err != nil {
            panic(err)
        }
        if len(cipherbyte) < aes.BlockSize {
            panic("ciphertext too short")
        }
    
        iv := cipherbyte[:aes.BlockSize]
        cipherbyte = cipherbyte[aes.BlockSize:]
        if len(cipherbyte)%aes.BlockSize != 0 {
            panic("ciphertext is not a multiple of the block size")
        }
    
        mode := cipher.NewCBCDecrypter(block, iv)
        mode.CryptBlocks(cipherbyte, cipherbyte)
    
        //fmt.Printf("%s
    ", ciphertext)
        plaintext = string(cipherbyte[:])
        return
    }
    
    /*
        AES  GCM 加密
        key:加密key
        plaintext:加密明文
        ciphertext:解密返回字节字符串[ 整型以十六进制方式显示]
    
    */
    func AESGCMEncrypt(key, plaintext string) (ciphertext, noncetext string) {
        plainbyte := []byte(plaintext)
        keybyte := []byte(key)
        block, err := aes.NewCipher(keybyte)
        if err != nil {
            panic(err.Error())
        }
    
        // 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。
        nonce := make([]byte, 12)
        if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
            panic(err.Error())
        }
    
        aesgcm, err := cipher.NewGCM(block)
        if err != nil {
            panic(err.Error())
        }
    
        cipherbyte := aesgcm.Seal(nil, nonce, plainbyte, nil)
        ciphertext = fmt.Sprintf("%x
    ", cipherbyte)
        noncetext = fmt.Sprintf("%x
    ", nonce)
        return
    }
    
    /*
        AES  CBC 解码
        key:解密key
        ciphertext:加密返回的串
        plaintext:解密后的字符串
    */
    func AESGCMDecrypter(key, ciphertext, noncetext string) (plaintext string) {
        cipherbyte, _ := hex.DecodeString(ciphertext)
        nonce, _ := hex.DecodeString(noncetext)
        keybyte := []byte(key)
        block, err := aes.NewCipher(keybyte)
        if err != nil {
            panic(err.Error())
        }
    
        aesgcm, err := cipher.NewGCM(block)
        if err != nil {
            panic(err.Error())
        }
    
        plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil)
        if err != nil {
            panic(err.Error())
        }
    
        //fmt.Printf("%s
    ", ciphertext)
        plaintext = string(plainbyte[:])
        return
    }

    使用很简单:

    key := "example key 1234"
    plaintext := "exampleplaintext"
    ciphertext := utils.AESCBCEncrypt(key, plaintext)
    fmt.Println(ciphertext)
    
    plaintext = utils.AESCBCDecrypter(key, ciphertext)
    fmt.Println(plaintext)
    ///GCM
    noncetext := ""
    ciphertext, noncetext = utils.AESGCMEncrypt(key, plaintext)
    fmt.Println(ciphertext)
    
    plaintext = utils.AESGCMDecrypter(key, ciphertext, noncetext)
    fmt.Println(plaintext)
  • 相关阅读:
    Python标准模块--concurrent.futures 进程池线程池终极用法
    线程,线程池
    常用英文单词
    进程池
    三种方法实现 生产者消费者模型
    进程间通信IPC -- 管道, 队列
    jquery 和 css 属性
    javascript的 Object 和 Function
    nodejs 返回html页面--使用 ejs 模板
    jquery属性
  • 原文地址:https://www.cnblogs.com/majiang/p/14163608.html
Copyright © 2011-2022 走看看