phpgoencryptioncryptographyblowfish

Matching blowfish encryption in php openssl_encrypt and golang blowfish


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";

This prints(first line is IV, second one is encrypted text:

253 145 220 198 224 78 40 124 
208 51 12 30 46 92 13 181 19 210 50 57 174 207 93 130 

Copying that IV to 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
}

I get:

[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]

I Tried with ECB mode as well. I was able to match first 8 bytes once but I messed something up. I'm trying to figure out how the php version handles it so that I can match go implementation, but I'm failing so far.


Solution

  • The following issues cause the different results: