2
votes

Working with guacamole-auth-json, coding php client implementation.

I need to be able to encrypt hmac sha256 hashed json with aes-128-cbc cipher. I have same input data with hash, but failing to implement encryption.

Working guacamole-auth-json example in bash

#!/bin/bash -e

##
## Encryption/signing key.
##
SECRET_KEY="$1"

##
## The filename of the JSON data being signed and encrypted.
##
JSON_FILENAME="$2"
##

## A null (all zeroes) IV.
##
NULL_IV="00000000000000000000000000000000"

##
## Signs the contents of the given file using the given key. The signature is
## created using HMAC/SHA-256, and is output in binary form to STDOUT, followed
## by the raw contents of the file.
##
## @param KEY
##     The key to use to sign the contents of the given file with HMAC/SHA-256.
##
## @param FILENAME
##     The filename of the file to sign.
##
sign() {

    KEY="$1"
    FILENAME="$2"

    #
    # Write out signature
    #

    openssl dgst                                \
        -sha256 -mac HMAC -macopt hexkey:"$KEY" \
        -binary "$FILENAME"

    #
    # Write out file contents
    #

    cat "$FILENAME"

}

##
## Encrypts all data received through STDIN using the provided key. Data is
## encrypted using 128-bit AES in CBC mode (with a null IV). The encrypted
## result is printed to STDOUT encoded with base64.
##
## @param KEY
##     The key to encrypt STDIN with, as a 16-byte (32-digit) hexadecimal
##     value.
##
encrypt() {

    KEY="$1"

    #
    # Encrypt STDIN
    #

    openssl enc -aes-128-cbc -K "$KEY" -iv "$NULL_IV" -nosalt -a

}

#
# Sign and encrypt file using secret key
#
sign "$SECRET_KEY" "$JSON_FILENAME" | encrypt "$SECRET_KEY"

My other data producing php implementation

$auth_json = "{\n";
$auth_json = $auth_json . "    \"username\" : \"\",\n";
$auth_json = $auth_json . "    \"expires\" : \"1607500000000\",\n";
$auth_json = $auth_json . "    \"connections\" : {\n";
$auth_json = $auth_json . "        \"Trading server 001\" : {\n";
$auth_json = $auth_json . "            \"protocol\" : \"" . get_post_meta( $post->ID,'trading_server_protocol', true ) . "\",\n";
$auth_json = $auth_json . "            \"parameters\" : {\n";
$auth_json = $auth_json . "                \"hostname\" : \"" . get_post_meta( $post->ID,'trading_server_hostname', true ) . "\",\n";
$auth_json = $auth_json . "                \"port\" : \"" . get_post_meta( $post->ID,'trading_server_port', true ) . "\",\n";
$auth_json = $auth_json . "                \"password\" : \"" . get_post_meta( $post->ID,'trading_server_password', true ) . "\",\n";
$auth_json = $auth_json . "                \"read-only\" : \"" . get_post_meta( $post->ID,'trading_server_readonly', true ) . "\"\n";
$auth_json = $auth_json . "            }\n";
$auth_json = $auth_json . "        }\n";
$auth_json = $auth_json . "    }\n";
$auth_json = $auth_json . "}";
            
$encrypt_key = "12345678901234567890123456789012";
$NULL_IV="00000000000000000000000000000000";
// HMAC Hex to byte
$secret     = hex2bin($encrypt_key);
$auth_json_hash = hash_hmac("sha256", $auth_json, $secret);
$auth_json_hash_bin = hash_hmac("sha256", $auth_json, $secret, true);
            
$cipher = "AES-128-CBC";
$data = $auth_json_hash_bin . $auth_json;
$auth_json_encrypted_raw = openssl_encrypt( $data, $cipher, $encrypt_key, $options = OPENSSL_RAW_DATA, $NULL_IV );
$auth_json_encrypted_base64 = base64_encode( $auth_json_encrypted_raw );

I have same hash, but not able to call openssl_encrypt function with same result as produced using bash example.

There is probably some problem with difference between

openssl enc -aes-128-cbc -K "$KEY" -iv "$NULL_IV" -nosalt -a

and

openssl_encrypt( $data, $cipher, $encrypt_key, $options = OPENSSL_RAW_DATA, $NULL_IV )

I understand, that I need to base64 encode result in php (-a switch) and need some solution for (-nosalt switch).

1
Hint: Dont build JSON manually. Create an object/array or mixture of both and then use JSON_ENCODE() to make the JSON StringRiggsFolly
Key and IV encoding is likely different (hex in bash and raw bytes in php)Artjom B.
Thanks, that is correct, found it myself just in the same time. :-)Jan Blaha

1 Answers

1
votes

Problem was with hex parameters (encrypt_key, NULL_IV) in php.

Correct code should be

$encrypt_key = "12345678901234567890123456789012";
$NULL_IV="00000000000000000000000000000000";
..
$auth_json_encrypted_raw = openssl_encrypt( $data, $cipher, hex2bin($encrypt_key), $options = OPENSSL_RAW_DATA, hex2bin($NULL_IV) );