当前位置: 首页 > 面试题库 >

Golang,使用AES和Base64加密字符串

严子默
2023-03-14
问题内容

我正在尝试加密数据库中的一些文本,以便在程序启动期间进行加载和解密。

我尝试了几种方法,包括第三方库https://github.com/richard-lyman/lithcrypt无济于事。使用以下方法对8/10项进行加密/解密,但是似乎在加密/解密中的某些时候留下了一些填充残留。就目前而言,我的代码是这样的:

package client                                                                                                                                                                                              
import (                                                                                                                                                                                                    
    "encoding/base64"                                                                                                                                                                                       
    "crypto/aes"                                                                                                                                                                                            
    "crypto/cipher"                                                                                                                                                                                         
    "fmt"                                                                                                                                                                                                   
)

var iv = []byte{34, 35, 35, 57, 68, 4, 35, 36, 7, 8, 35, 23, 35, 86, 35, 23}

func encodeBase64(b []byte) string {                                                                                                                                                                        
    return base64.StdEncoding.EncodeToString(b)                                                                                                                                                             
}

func decodeBase64(s string) []byte {                                                                                                                                                                        
    data, err := base64.StdEncoding.DecodeString(s)                                                                                                                                                         
    if err != nil { panic(err) }                                                                                                                                                                            
    return data                                                                                                                                                                                             
}

func Encrypt(key, text string) string {                                                                                                                                                                     
    block, err := aes.NewCipher([]byte(key))                                                                                                                                                                
    if err != nil { panic(err) }                                                                                                                                                                            
    plaintext := []byte(text)                                                                                                                                                                               
    cfb := cipher.NewCFBEncrypter(block, iv)                                                                                                                                                                
    ciphertext := make([]byte, len(plaintext))                                                                                                                                                              
    cfb.XORKeyStream(ciphertext, plaintext)                                                                                                                                                                 
    return encodeBase64(ciphertext)                                                                                                                                                                         
}

func Decrypt(key, text string) string {                                                                                                                                                                     
    block, err := aes.NewCipher([]byte(key))                                                                                                                                                                
    if err != nil { panic(err) }                                                                                                                                                                            
    ciphertext := decodeBase64(text)                                                                                                                                                                        
    cfb := cipher.NewCFBEncrypter(block, iv)                                                                                                                                                                
    plaintext := make([]byte, len(ciphertext))                                                                                                                                                              
    cfb.XORKeyStream(plaintext, ciphertext)                                                                                                                                                                 
}

有人告诉我,我可能需要填充字符串,但是我不得不填充流密码似乎很奇怪。

下面是此错误的示例:http :
//play.golang.org/p/4FQBAeHgRs


问题答案:

这基于NewCFBEncrypter /
NewCFBDecrypter示例,
并且似乎可以满足您的要求:

编辑:基于Kluyg关于IV创建的评论,我修改了示例代码,以使用 推荐的从密文创建IV的
方法,与链接示例从密文创建IV的方法相同。(在生产代码中,每次应单独生成IV。感谢RoundSparrowhilltx]指出了这一点。

我认为您遇到的问题是由于密钥长度无效,但是我不确定100%。

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/base64"
    "errors"
    "fmt"
    "io"
    "log"
)

func main() {
    key := []byte("a very very very very secret key") // 32 bytes
    plaintext := []byte("some really really really long plaintext")
    fmt.Printf("%s\n", plaintext)
    ciphertext, err := encrypt(key, plaintext)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%0x\n", ciphertext)
    result, err := decrypt(key, ciphertext)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", result)
}

// See alternate IV creation from ciphertext below
//var iv = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 05}

func encrypt(key, text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    b := base64.StdEncoding.EncodeToString(text)
    ciphertext := make([]byte, aes.BlockSize+len(b))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        return nil, err
    }
    cfb := cipher.NewCFBEncrypter(block, iv)
    cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
    return ciphertext, nil
}

func decrypt(key, text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    if len(text) < aes.BlockSize {
        return nil, errors.New("ciphertext too short")
    }
    iv := text[:aes.BlockSize]
    text = text[aes.BlockSize:]
    cfb := cipher.NewCFBDecrypter(block, iv)
    cfb.XORKeyStream(text, text)
    data, err := base64.StdEncoding.DecodeString(string(text))
    if err != nil {
        return nil, err
    }
    return data, nil
}

产生:

一些真的真的很长的纯文本

54618bd6bb10612a7b590c53192df214501e01b685540b012581a0ed9ff3ddaa1f4177cc6186b501fb8cce0c2eb764daff475aab724d4d33e614d7d89cf556d8512fd920018c090f
一些真的真的很长的纯文本

操场

希望这有助于查明问题。



 类似资料:
  • 所以我有一个AES-256-ecb base64字符串,我用在线工具解码了它。然而,我更喜欢命令行,所以我尝试使用命令行来解码它。 这是我尝试过的,但我得到了严重的解密错误 是加密的base64文本 -aes-256-ecb是加密密码 而366a74cb3c959de17d61db30591c39d1是关键 结果应该是另一个base64字符串:

  • 注意:这只是为个人使用和学习,我不是试图滚动我自己的加密为公众使用。 我需要AES256加密一个字符串,但是我当前的尝试在十六进制解码时最终得到了一个类似server side的字符串。当十六进制解码时,它应该是一个有效的utf8 base64字符串,然后可以将其解码为原始字符串。这与这里提供的解决方案类似,但是salt并不是实际问题(尽管答案被接受),并且我无法在使用之前通过十六进制解码iv来抑

  • 我一直在到处寻找一些示例代码,介绍如何使用Bouncy Castle框架用标题中的加密加密一个简单的字符串。 此代码将在Windows Universal项目上运行。我以前尝试使用内置API进行加密,但在服务器上解密失败。 服务器使用 但失败的原因是: 填充无效,无法删除。 初始化向量的长度必须与块大小相同 服务器上的长度为128。我怎么能强迫它是等长的?

  • 我正在尝试在Go中加密数据,并使用带有PKCS7填充的AES CBC模式在Angular中解密。但是当我尝试在Angular中解密数据时,它没有返回任何内容 Go代码: Angular/CryptoJs代码: 我从加密JS解密方法中得到一个空响应。 cryptoJS的iv值应该是多少?

  • 问题内容: 这是我在Node.js中拥有的: 返回: 这就是我在Go中所拥有的: 最终返回 许多Go代码都来自https://gist.github.com/manishtpatel/8222606 我也尝试过此方法:如何在golang中解密在nodejs中加密的AES256位密码?(在这种情况下,无需进行一些修改),但会抛出错误 这是我尝试的代码: 我搜索了很多东西,但似乎无法弄清楚。 我究竟做

  • 问题内容: 但只有3个参数。我需要一种方法来做这样的事情: 问题答案: 通常,您不需要为具有确定性行为的算法生成随机数的对象。此外,在使用ECB块模式时,您不需要IV,这是Java默认设置。确切地说,Java默认为中的for 。 因此,您应该可以使用如下代码: 现在看起来好多了。我已使用Apache Commons编解码器解码十六进制字符串。 请注意,您需要保存与和你有没有包括完整性保护,如MAC