第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

將 PHP AES 加密移植到 Golang

將 PHP AES 加密移植到 Golang

Go
BIG陽 2022-07-04 16:46:46
我的電子商務(wù)提供商在 PHP、Java、JavaScript、C# 和 Python 中有這個(gè)庫(kù)來加密我的請(qǐng)求,因?yàn)槲业?API 是用 Go 制作的,我自然想,為什么不用 Go 做呢?哦,男孩……我不知道我在做什么。這是原始的PHP代碼:class AesCrypto {    /**    * Encrypt string with a given key    * @param strToEncrypt    * @param key    * @return String encrypted string    */    public static function encrypt($plaintext, $key128) {        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-128-cbc'));        $cipherText = openssl_encrypt($plaintext, 'AES-128-CBC', hex2bin($key128), 1, $iv);        return base64_encode($iv.$cipherText);    }}我用 Go 嘗試了幾種略有不同的方法,我想最低限度是這樣的:func encrypt(text string, key string) string {    data := []byte(text)    block, _ := aes.NewCipher([]byte(key))    gcm, err := cipher.NewGCM(block)    if err != nil {        panic(err.Error())    }    nonce := make([]byte, gcm.NonceSize())    if _, err = io.ReadFull(rand.Reader, nonce); err != nil {        panic(err.Error())    }    ciphertext := gcm.Seal(nonce, nonce, data, nil)    encoded := base64.StdEncoding.EncodeToString([]byte(ciphertext))    return encoded}我創(chuàng)建了這個(gè)函數(shù)來加密和解密,它們工作正常,但是當(dāng)我將它發(fā)送給我的提供商時(shí)它不起作用。由key電子商務(wù)提供商分配,長(zhǎng)度為 32 個(gè)字節(jié),我知道長(zhǎng)度“告訴”newCipher選擇 AES-256,對(duì)嗎?那么它永遠(yuǎn)不會(huì)對(duì)應(yīng)于 AES-128,如 PHP func 中所示。除了檢查我的電子商務(wù)提供商的服務(wù)或嘗試使用 PHP 代碼解密之外,我該如何移植此 PHP 代碼?這是另一個(gè)嘗試(來自 Go 加密文檔):func encrypt4(text string, keyString string) string {    key, _ := hex.DecodeString(keyString)    plaintext := []byte(text)    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)    final := base64.StdEncoding.EncodeToString(ciphertext)    return final}
查看完整描述

1 回答

?
白板的微信

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個(gè)贊

GCM 與 CBC 模式不同。密鑰是十六進(jìn)制編碼的,所以一個(gè) 32 字節(jié)的字符串代表一個(gè) 16 字節(jié)(或 128 位)的密鑰。

在 CBC 模式下,明文必須被填充,以便它是塊大小的倍數(shù)。PHP 的 openssl_encrypt 自動(dòng)執(zhí)行此操作(使用PKCS#5/7),但在 Go 中必須明確完成。

綜上所述,我們最終得到了文檔中 CBC 加密示例的輕微變化:

package main


import (

    "bytes"

    "crypto/aes"

    "crypto/cipher"

    "crypto/rand"

    "encoding/base64"

    "encoding/hex"

    "io"

)


func encrypt(plaintext, key16 string) string {

    padded := pkcs7pad([]byte(plaintext), aes.BlockSize)


    key, err := hex.DecodeString(key16)

    if err != nil {

        panic(err)

    }


    block, err := aes.NewCipher(key)

    if err != nil {

        panic(err)

    }


    buffer := make([]byte, aes.BlockSize+len(padded)) // IV followed by ciphertext

    iv, ciphertext := buffer[:aes.BlockSize], buffer[aes.BlockSize:]


    if _, err := io.ReadFull(rand.Reader, iv); err != nil {

        panic(err)

    }


    mode := cipher.NewCBCEncrypter(block, iv)

    mode.CryptBlocks(ciphertext, padded)


    return base64.StdEncoding.EncodeToString(buffer)

}


func pkcs7pad(plaintext []byte, blockSize int) []byte {

    padding := blockSize - len(plaintext)%blockSize


    return append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...)

}


查看完整回答
反對(duì) 回復(fù) 2022-07-04
  • 1 回答
  • 0 關(guān)注
  • 257 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)