【问题标题】:Golang: How do I decrypt with DES, CBC, and PKCS7?Golang:如何使用 DES、CBC 和 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 哎呀!谢谢你接听。

标签: go base64 des pkcs#7 cbc-mode


【解决方案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([]byte{byte(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 := []byte{0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC }
        iv := []byte{0xBC, 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([]byte{byte(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)
}

【讨论】:

    猜你喜欢
    • 2017-10-11
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多