Golang:如何使用 DES、CBC 和 PKCS7 解密?
Posted
技术标签:
【中文标题】Golang:如何使用 DES、CBC 和 PKCS7 解密?【英文标题】:Golang: How do I decrypt with DES, CBC, and PKCS7? 【发布时间】:2017-01-10 22:10:39 【问题描述】:目前正试图弄清楚为什么我的解密方法不起作用。我使用 DES、CBC 和 PKCS7Padding 来加密我的字符串。我当前的code 在解密期间输出panic: crypto/cipher: input not full blocks
。
【问题讨论】:
1.不要使用 DES,它不安全,并且已被 AES 取代,AES 并不难使用。 2. 使用随机IV,只需在加密数据前加上IV前缀,用于解密(IV不需要保密)。当相同的加密密钥用于多条消息时,使用不同的 IV 很重要。 3. 考虑一下,加密的目的通常是为了创造安全性,使用不当的加密不会提供安全性。 不清楚你想解密一个12个字符的加密字符串并指定一个唯一的密钥和一个唯一的IV。必须使用用于加密的相同密钥和 IV 进行解密。这个问题可以更清楚,并提供更多关于你想要完成的事情的信息。 对于初学者来说,解密时您没有解码 base64,这就是数据大小错误的原因。 @zaph 感谢您的反馈和见解。我的代码是本地原型,而不是生产代码。 @JimB 哎呀!谢谢你接听。 【参考方案1】:伙计,它工作得很好。
package main
import (
"bytes"
"crypto/des"
"crypto/cipher"
"fmt"
)
func DesEncryption(key, iv, plainText []byte) ([]byte, error)
block, err := des.NewCipher(key)
if err != nil
return nil, err
blockSize := block.BlockSize()
origData := PKCS5Padding(plainText, blockSize)
blockMode := cipher.NewCBCEncrypter(block, iv)
cryted := make([]byte, len(origData))
blockMode.CryptBlocks(cryted, origData)
return cryted, nil
func DesDecryption(key, iv, cipherText []byte) ([]byte, error)
block, err := des.NewCipher(key)
if err != nil
return nil, err
blockMode := cipher.NewCBCDecrypter(block, iv)
origData := make([]byte, len(cipherText))
blockMode.CryptBlocks(origData, cipherText)
origData = PKCS5UnPadding(origData)
return origData, nil
func PKCS5Padding(src []byte, blockSize int) []byte
padding := blockSize - len(src)%blockSize
padtext := bytes.Repeat([]bytebyte(padding), padding)
return append(src, padtext...)
func PKCS5UnPadding(src []byte) []byte
length := len(src)
unpadding := int(src[length-1])
return src[:(length - unpadding)]
func main()
originalText := "sysys"
fmt.Println(originalText)
mytext := []byte(originalText)
key := []byte0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC
iv := []byte0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC
cryptoText,_ := DesEncryption(key, iv, mytext)
fmt.Println(string(cryptoText))
decryptedText,_ := DesDecryption(key, iv, cryptoText)
fmt.Println(string(decryptedText))
【讨论】:
是的!谢谢!我只是在 main 中更改了一行。我将fmt.Println(string(cryptoText))
更改为fmt.Println(base64.URLEncoding.EncodeToString(cryptoText))
。
最好使用这个填充/取消填充代码:github.com/go-web/tokenizer/blob/master/pkcs7.go【参考方案2】:
你可以这样做
package controllers
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
)
func PKCS7Padding(ciphertext []byte) []byte
padding := aes.BlockSize - len(ciphertext) % aes.BlockSize
padtext := bytes.Repeat([]bytebyte(padding), padding)
return append(ciphertext, padtext...)
func PKCS7UnPadding(plantText []byte) []byte
length := len(plantText)
unpadding := int(plantText[length-1])
return plantText[:(length - unpadding)]
func OpensslDecrypt(keyStr string, ivStr string, text string) string
key, _ := hex.DecodeString(keyStr);
iv, _ := hex.DecodeString(ivStr);
ciphertext, _ := hex.DecodeString(text);
block, err := aes.NewCipher(key)
if err != nil
panic(err)
plaintext := make([]byte,len(ciphertext))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, ciphertext)
plaintext = PKCS7UnPadding(plaintext)
return fmt.Sprintf("%s\n", plaintext)
func OpensslEncrypt(keyStr string, ivStr string, text string) string
plaintext := []byte(text)
key, _ := hex.DecodeString(keyStr);
iv, _ := hex.DecodeString(ivStr);
plaintext = PKCS7Padding(plaintext);
ciphertext := make([]byte,len(plaintext))
block, err := aes.NewCipher(key)
if err != nil
panic(err)
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return fmt.Sprintf("%x\n", ciphertext)
【讨论】:
以上是关于Golang:如何使用 DES、CBC 和 PKCS7 解密?的主要内容,如果未能解决你的问题,请参考以下文章