Golang用AES和Base64加密字符串 [英] Golang, encrypting a string with AES and Base64

查看:207
本文介绍了Golang用AES和Base64加密字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图加密数据库中的一些文本,以在程序启动期间加载和解密。我尝试过几种方法,包括第三方库 https://github.com/richard-lyman/lithcrypt 无效。使用以下方法加密/解密8/10个项目,但似乎在加密/解密中的某个时间点留下了一些填充残差。因为它是我的代码是这样的:

 包客户端
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)}
返回数据
}

func加密(key,text string)string {
block,err:= aes.NewCipher([] byte(key))
如果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解密(key,text string)string {
block,err:= aes.NewCipher([] byte(key))
如果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。 org / pkg / crypto / cipher /#example_NewCFBDecrypterrel =nofollow noreferrer>链接示例从密文创建IV。 (在生产代码中,每次都应该单独生成IV,感谢 RoundSparrow hilltx 指出这一点。)



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



$ $ $ $ $ $ $ $ $ $ $ $ $


$加密/ aes
加密/ rand
encoding / base64
错误
fmt
io
日志


func main(){
key:= [] byte(非常非常非常非常秘密的密钥)// 32 bytes
plaintext:= [] byte(some really really long long plaintext )
fmt.Printf(%s\\\
,plaintext)
ciphertext,err:= encrypt(key,plaintext)
如果err!= nil {
log fatal(err)
}
fmt.Printf(%0x\\\
,ciphertext)
result,err:= decrypt(key,ciphertext)
如果err! = nil {
log.Fatal(err)
}
fmt.Printf(%s\\\
,result)
}

//查看从密文创建的替代IV低于
// var iv = [] byte {35,46,57,24,85,35,24,44,87,35,88,98,66,32,45,5}

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))
返回密文,nil
}

func decrypt(key,text [] byte)([] byte,error){
block ,err:= aes.NewCipher(key)
如果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)
如果err!= nil {
return nil,err
}
返回数据,nil
}

产生:


一些真的真的很长的明文

54618bd6bb10612a7b590c53192df214501e01b685540b012581a0ed9ff3ddaa1f4177cc6186b501fb8cce0c2eb764daff475aab724d4d33e614d7d89cf556d8512fd920018c090f点击
一些真的真的真的很长的明文




游乐场



希望有助于指出问题。


I'm trying to encrypt some text inside a database to be loaded and decrypted during program startup.

I have tried a few methods, including a third party library https://github.com/richard-lyman/lithcrypt to no avail. Using the following method encrypts/decrypts 8/10 items, but it seems that some padding residue is left behind at some point in the encrypt/decrypt. As it stands my code is like this:

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)                                                                                                                                                                 
}                          

It was mentioned to me that I might need to pad the string, but it seems strange that I would have to pad a stream cipher.

Below is an example of this error: http://play.golang.org/p/4FQBAeHgRs

解决方案

This is based on the NewCFBEncrypter / NewCFBDecrypter examples and seems to do what you require:

EDIT: Based on Kluyg's comment regarding IV creation I've modified the example code to use the recommended method of creating the IV from the ciphertext same method as the linked example to create the IV from the ciphertext. (In production code the IV should be generated seperately each time. Thanks to RoundSparrow hilltx for pointing this out.)

I think the problem you're encountering is due to an invalid key length, but I'm not 100% sure.

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
}

Produces:

some really really really long plaintext
54618bd6bb10612a7b590c53192df214501e01b685540b012581a0ed9ff3ddaa1f4177cc6186b501fb8cce0c2eb764daff475aab724d4d33e614d7d89cf556d8512fd920018c090f
some really really really long plaintext

Playground

Hope that helps to pin point the problem.

这篇关于Golang用AES和Base64加密字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆