首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(Go)加密/解密字符串会导致字符丢失

(Go)加密/解密字符串会导致字符丢失
EN

Stack Overflow用户
提问于 2022-11-13 03:44:30
回答 3查看 86关注 0票数 1

我试图在存储敏感数据之前对其进行加密。首先,我生成一个用于加密过程的密钥:

代码语言:javascript
复制
import (
    "crypto/aes"
    CR "crypto/rand"
    "encoding/hex"
    "errors"
    "log"
    "os"
)

// []byte key used to encrypt tokens before saving to local file system
var key = make([]byte, 32)

func createKey(key *[]byte) {
    _, err = CR.Read(*key)
    if err != nil {
        log.Println("Error creating key from crypto/rand package:", err)
    }
}

接下来,我创建了分别加密和解密字符串的函数:

代码语言:javascript
复制
func encryptToken(t token) string {
    original := t.ID // ID is string member of token

    cipher, err := aes.NewCipher(key)
    if err != nil {
        log.Println("Error creating cipher during encrypt:", err)
    }

    out := make([]byte, len(original))
    cipher.Encrypt(out, []byte(original))

    return hex.EncodeToString(out) // this will be written to a csv file 

    // appears in file as: cec35df876e1b77diefg9023366c5f2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
}

func decryptToken(s string) string {
    ciphertext, err := hex.DecodeString(s) // s is read from csv file
    if err != nil {
        log.Println("Error decoding string from hex:", err)
    }

    cipher, err := aes.NewCipher(key)
    if err != nil {
        log.Println("Error creating cipher during decrypt:", err)
    }

    original := make([]byte, len(ciphertext))
    cipher.Decrypt(original, ciphertext)

    originalAsString := string(original[:])

    return originalAsString  // returns: 6f928e728f485403

    // original token was: 6f928e728f485403e254049f684ea5ec853adcfa9553cdfc956fr45671447c57
}

考虑到encryptToken()返回一个包含如此多零的十六进制字符串,我确信这就是我的问题所在。我已经尝试过调整key的长度,但是在var key = make([]byte, 32)中使用32以外的值将导致出现涉及无效内存地址或零指针取消引用的恐慌。为什么会这样呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-11-13 09:02:35

最短的答案可能是:正如@GradyPlayer建议的那样,您使用密码的方式是错误的。您必须将其交给加密器,后者将其应用于所有字节。模式看起来是这样的:

代码语言:javascript
复制
ciphertext = make([]byte, len(plaintext))
cbc := cipher.NewCBCEncrypter(cipher, iv)
cbc.CryptBlocks(ciphertext, plaintext)

尽管如此,在这里您仍然需要将初始化向量放在密文前面(至少这是放置它的通常位置,解密器可能希望它位于这里),您仍然需要考虑填充(如果您像我一样使用CBC )。

因此,虽然它没有直接解决这个问题,但我认为它可以帮助您获得更多的代码,以便更好地理解。这里是我刚刚创建的一个要点。免责声明:我主要是从其他地方组装代码片段。所以,我只是把你在这里看到的片段放在一起,在路上获得了一些了解。

票数 3
EN

Stack Overflow用户

发布于 2022-11-13 03:51:45

我不太熟悉这个库,但是它可能只是在做一个AES的块,AES是一个16字节的分组密码,这似乎是你得到的,一个16字节的代码块。要完成整个AES的任意块,您必须将其放入一个full size mod 16 = 0字节(查找PKCS5 5/7,然后执行一个块.然后,要么是CTR或CBC ( IV来自最后一个块的位置或输出),然后是下一个块等等.因此,我认为您使用的是AES块原语,而不是整块之类的东西(除了键外,还需要块模式和iv)。

票数 2
EN

Stack Overflow用户

发布于 2022-11-13 12:34:47

以下按注释编辑(为了正确地使用nonce):

接受的答案,特别是来自Topaco的评论,帮助我找到了这个解决方案,我在这里为任何可能遇到这种情况的人发帖子:

代码语言:javascript
复制
var key = make([]byte, 32)

func encryptToken(t token) string {
    original := t.ID // ID is string member of token
    var nonce = make([]byte, 12)

    // read random bytes into nonce
    _, err := rand.Read(nonce)
    if err != nil {
        log.Println("Error reading random bytes into nonce:", err)
    }

    block, err := aes.NewCipher(key)
    if err != nil {
        log.Println("Error creating cipher during encrypt:", err)
    }

    aesgcm, err := cipher.NewGCM(block)
    if err != nil {
        log.Println("Error creating GCM during encrypt:", err)
    }

    ciphertext := aesgcm.Seal(nil, nonce, []byte(original), nil)

    // prepend the ciphertext with the nonce
    out := append(nonce, ciphertext...)

    return hex.EncodeToString(out)
}

func decryptToken(s string) string {
    // read hex string describing nonce and ciphertext
    enc, err := hex.DecodeString(s)
    if err != nil {
        log.Println("Error decoding string from hex:", err)
    }

    // separate ciphertext from nonce
    nonce := enc[0:12]
    ciphertext := enc[12:]

    block, err := aes.NewCipher(key)
    if err != nil {
        log.Println("Error creating cipher during decrypt:", err)
    }

    aesgcm, err := cipher.NewGCM(block)
    if err != nil {
        log.Println("Error creating GCM during decrypt:", err)
    }

    original, err := aesgcm.Open(nil, nonce, ciphertext, nil)
    if err != nil {
        log.Println("Error decrypting to string:", err)
    }
    originalAsString := string(original)

    return originalAsString
}

参考资料:https://pkg.go.dev/crypto/cipher#example-NewGCM-Encrypt

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74418323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档