【问题标题】:How to encrypt String or JSON [closed]如何加密字符串或 JSON [关闭]
【发布时间】:2021-03-01 14:37:26
【问题描述】:

我正在尝试使用以下代码加密 Go 中的一些文本:

key, _ := hex.DecodeString("6368616e676520746869732070617373")
plaintext := []byte("exampleplaintext")
if len(plaintext)%aes.BlockSize != 0 {
    panic("plaintext is not a multiple of the block size")
}
block, err := aes.NewCipher(key)
if err != nil {
    panic(err)
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
    panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext) 

我得到了这个结果:

891cf7c418d2d1cd4e5c9db05b092e50d5a25e9e4ce4f5f799efdb82596e32a9

Link在golang play上面的代码

一切正常,但是当我在输入中添加空格和换行符时,它不起作用我收到错误:

panic: plaintext is not a multiple of the block size

Link转码

我的问题是我是否必须像这样对字符串进行编码:

t := ` {
    "mobileNum": "9999999999",
    "osVersion": "",
    "AppId": "hhhhhh88888",
    "panNo": "AXXXXXXXXX",
    "osType": "",
    "emailId": "nxxxxxxxxx@gmail.com",
    "deviceID": ""
}`

那我该怎么办?

【问题讨论】:

  • 您的代码只是稍微偏离了目标。基本上在 AES 中你有一个块大小,而 AES 只能处理长度是块大小的倍数的字节切片,因此对于 25 的 len,你应该将长度设置为 32(上一个块大小)。
  • 另外,您的策略似乎是附加 nul 字节以匹配块大小,这可能看起来并不但这是危险的(是的,加密是不公平的 :)),您应该尝试使用填充算法(即还将保持您的数据完整):stackoverflow.com/a/13572751/8537707
  • 这不是你想听到的答案,但请不要自己做这些事情,特别是如果你不确定加密是如何工作的。请使用预包装的常用工具,例如golang.org/x/crypto/nacl/secretbox
  • @NilaySingh 我给了你那个工具:golang.org/x/crypto/nacl/secretbox 你还需要什么? NaCl的哪一部分不清楚?

标签: go encryption


【解决方案1】:

AES 只能处理 len 是其块大小倍数的字节片。 所以你应该把你的 len 限制到下一个块大小。 这将添加一些空字节来填补空白,即使这个接缝是合理的,这不是出于两个原因:

  • 这会损坏您的数据(对于 json 可能不是问题,但如果您正在处理让我们说视频文件有问题)。
  • 这很危险(是的,加密是不公平的 :)),这不会泄露您的整个密钥,但会简化攻击。

你可以看看https://gist.github.com/huyinghuan/7bf174017bf54efb91ece04a48589b22的例子,这个例子使用AES和PCKS进行填充。

【讨论】:

    猜你喜欢
    • 2012-11-30
    • 2013-02-15
    • 2021-10-20
    • 2023-01-12
    • 1970-01-01
    • 2020-12-13
    • 2018-10-31
    • 1970-01-01
    • 2018-06-08
    相关资源
    最近更新 更多