首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >php openssl_encrypt和golang河豚的匹配河豚加密

php openssl_encrypt和golang河豚的匹配河豚加密
EN

Stack Overflow用户
提问于 2020-09-17 09:08:18
回答 1查看 393关注 0票数 1

PHP:

代码语言:javascript
运行
复制
$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,第二行为加密文本:

代码语言:javascript
运行
复制
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复制到戈朗:

代码语言:javascript
运行
复制
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
}

我得到:

代码语言:javascript
运行
复制
[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]

我也尝试过欧洲央行的模式。我能匹配前8个字节一次,但我搞砸了。我试图弄清楚php版本是如何处理它的,以便与go实现相匹配,但到目前为止我失败了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-17 12:14:15

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

  • 河豚的块大小为8字节,可变键大小为4至56字节。在PHP中,有一个用于Blowfish的错误,它用0值将较短的键压缩到16个字节。从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 97 183 42 220 119 173 26 156 153 152 139 105 237 这里有一个可以设置标志的联机PHP环境。
  • Go中定义的填充是零填充,而在PHP代码中,PKCS7填充被openssl使用(默认情况下)。对于PKCS7,以下更改是必要的(没有注释,使用相同的名称): 函数pad(pt []字节)[]字节{模:= len( pt ) % blowfish.BlockSize padlen := blowfish.BlockSize -模i := 0;i< padlen;i++ { pt = append(pt,字节(Padlen))}返回pt} 在进行此更改后,Go - Code将产生相同的结果: 253 145 220 198 224 78 40 124 结尾处的0是由于密文缓冲区太大而导致的。在Go代码中,输出缓冲区的长度是用明文长度加块大小(Blowfish的8个字节)计算的,这确保了有足够的空间填充,因为最大的填充是一个块。使用较短的填充时,缓冲区太大,例如,在当前情况下,明文的长度为9字节,这导致缓冲区为17字节。密文的长度为16字节,这将导致结尾处的0。如果需要,可以将所需的缓冲区大小确定为明文长度加上填充长度(后者类似于pad函数中的pad)。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63934788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档