为了账号安全,请及时绑定邮箱和手机立即绑定

Mcrypt 从 PHP 到 Go

Mcrypt 从 PHP 到 Go

Go
一只甜甜圈 2021-12-07 10:32:19
我使用一个类来加密/解密 PHP 中的字符串。如何在 Go 中加密/解密字符串?PHP 类:class Crypto {    private $encryptKey = 'xxxxxxxxxxxxxxxx';    private $iv = 'xxxxxxxxxxxxxxxx';    private $blocksize = 16;    public function decrypt($data)    {        return $this->unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,             $this->encryptKey,             hex2bin($data),            MCRYPT_MODE_CBC, $this->iv), $this->blocksize);    }    public function encrypt($data)    {        //don't use default php padding which is '\0'        $pad = $this->blocksize - (strlen($data) % $this->blocksize);        $data = $data . str_repeat(chr($pad), $pad);        return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,            $this->encryptKey,            $data, MCRYPT_MODE_CBC, $this->iv));    }    private function unpad($str, $blocksize)    {        $len = strlen($str);        $pad = ord($str[$len - 1]);        if ($pad && $pad <= $blocksize) {            if (substr($str, -$pad) === str_repeat(chr($pad), $pad)) {                return substr($str, 0, $len - $pad);            }        }        return $str;    }}什么能够在 PHP 和 Go 中加密/解密相同的字符串。
查看完整描述

1 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

下面是一个例子:


package main


import (

    "crypto/aes"

    "crypto/cipher"

    "crypto/rand"

    "encoding/base64"

    "errors"

    "fmt"

    "io"

    "log"

)


func main() {

    key := []byte("xxxxxxxxxxxxxxxx") // 32 bytes

    plaintext := []byte("TEST")

    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)

}


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

}

主要借鉴和改编自:https : //golang.org/src/crypto/cipher/example_test.go


// Input => TEST

// Output => 13360adba03733e11dd2702de441ff8bbb90676ad762fc83

更新


要将字符串用作decode函数的参数,您需要将字符串转换为byteusinghex.Decodestring


data, _ := hex.DecodeString("1d6f12d3aa2353b23c6012dbc85816632129363d58a76063")

result, err := decrypt(key, data)

if err != nil {

    log.Fatal(err)

}

fmt.Printf("%s\n", result)

不要忘记包含"encoding/hex"在包列表中。


查看完整回答
反对 回复 2021-12-07
  • 1 回答
  • 0 关注
  • 226 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信