gpt4 book ai didi

php - 在PHP openssl_encrypt和golang河豚中匹配河豚加密

转载 作者:行者123 更新时间:2023-12-01 20:24:37 27 4
gpt4 key购买 nike

PHP:

$key = "testtesttest";
$text = "bublijuja";
$iv = openssl_random_pseudo_bytes( openssl_cipher_iv_length("blowfish"));
for($i = 0; $i < strlen($iv); $i++)
{
echo ord($iv[$i])." ";
}
echo "\n";
$et = openssl_encrypt( $text, "blowfish", $key, OPENSSL_RAW_DATA, $iv );
for($i = 0; $i < strlen($et); $i++)
{
echo ord($et[$i])." ";
}
echo "\n";
打印(第一行是IV,第二行是加密的文本:
253 145 220 198 224 78 40 124 
208 51 12 30 46 92 13 181 19 210 50 57 174 207 93 130
将该IV复制到golang:
package main

import (
"golang.org/x/crypto/blowfish"
"crypto/cipher"
"fmt"
)



func main() {
key := "testtesttest"
plaintext := "bublijuja"
byteSlice := []int{253, 145, 220, 198, 224, 78, 40, 124}
iv := make([]byte, len(byteSlice))
for i, b := range byteSlice {
iv[i] = byte(b)
}
fmt.Println(iv)
ciphertext := make([]byte, blowfish.BlockSize+len(plaintext))
block, err := blowfish.NewCipher([]byte(key))
if err != nil {
fmt.Println(err.Error())
return
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, pad([]byte(plaintext)))

fmt.Println(ciphertext)
}


func pad(pt []byte) []byte {
// calculate modulus of plaintext to blowfish's cipher block size
// if result is not 0, then we need to pad
modulus := len(pt) % blowfish.BlockSize
if modulus != 0 {
// how many bytes do we need to pad to make pt to be a multiple of
//blowfish's block size?
padlen := blowfish.BlockSize - modulus
// let's add the required padding
for i := 0; i < padlen; i++ {
// add the pad, one at a time
pt = append(pt, 0)
}
}
// return the whole-multiple-of-blowfish.BlockSize-sized plaintext
// to the calling function
return pt
}
我得到:
[253 145 220 198 224 78 40 124]
[61 82 97 183 42 220 119 173 114 107 250 139 174 236 113 91 0]
我也尝试过ECB模式。
我一次可以匹配前8个字节,但是我搞砸了。
我试图弄清楚php版本是如何处理它的,以便可以匹配go的实现,但是到目前为止,我还是失败了。

最佳答案

以下问题导致不同的结果:

  • Blowfish的块大小为8个字节,可变 key 大小为4到56个字节。在PHP中,有一个针对Blowfish的bug,它将较短的键填充为16个字节(0值)。从7.1.8版本开始,有一个阻止此的标志:OPENSSL_DONT_ZERO_PAD_KEY。如果另外设置了此标志(OPENSSL_RAW_DATA | OPENSSL_DONT_ZERO_PAD_KEY),那么将在以下环境中输出以下输出:
    253 145 220 198 224 78 40 124 
    61 82 97 183 42 220 119 173 26 156 153 20 152 139 105 237
    Here有一个在线PHP环境,可以在其中设置标志。
  • 在Gos中定义的填充为零填充,而在PHP代码中,openssl使用PKCS7填充(默认)。对于PKCS7,需要进行以下更改(无注释,使用相同的名称):
    func pad(pt []byte) []byte {
    modulus := len(pt) % blowfish.BlockSize
    padlen := blowfish.BlockSize - modulus
    for i := 0; i < padlen; i++ {
    pt = append(pt, byte(padlen))
    }
    return pt
    }
    通过此更改,Go-Code给出了相同的结果:
    [253 145 220 198 224 78 40 124]
    [61 82 97 183 42 220 119 173 26 156 153 20 152 139 105 237 0]
    最后的0是由密文缓冲区太大引起的。在Go代码中,输出缓冲区的长度是用纯文本长度加上块大小(Blowfish为8字节)计算的,这确保了有足够的填充空间,因为最大的填充是一个块。如果填充时间较短,则缓冲区太大,例如在当前情况下,明文的长度为9个字节,这导致17个字节的缓冲区。密文的长度为16个字节,最后是0。如果需要,可以将确切需要的缓冲区大小确定为纯文本长度加上填充长度(后者的确定类似于padlen函数中的pad)。
  • 关于php - 在PHP openssl_encrypt和golang河豚中匹配河豚加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63934788/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com