2

So in this project I'm working on I'm currently trying to do a reset-password function which generates a URL which is then given to the user with a secret attached to it to be validated in the backend.

The problem is that the secret needs to be stored in the db (postgresql) in a bytea format. Is there a way to convert a UUID to a bytea format in php? I've tried some different variations of pack and unpack as well as a few functions I found on the interwebs but with no success.

I'm not allowed to alter the db in any way.

  • Why does it need to be stored in byte format? What difference does it make? – Starx Mar 21 '18 at 15:13
  • Because the feature I'm doing is pretty much a way for devs to help a user out by sending them this reset password url, and if it's stored in a wrong format the url sent to the user doesn't actually work. – Johan Lundgren Mar 21 '18 at 15:17
  • @Starx not certain for postgres, but i believe that byte-format speeds up indexing and query by UUID. – YvesLeBorg Mar 21 '18 at 15:17
  • `UNHEX` and `BIN` or PHP `hex2bin` but need to remove `-`. – AbraCadaver Mar 21 '18 at 15:17
  • @YvesLeBorg, Based on the response from OP, I don't think that is what he is after. – Starx Mar 21 '18 at 15:19
  • @Starx yep ... what out for those long queries :) – YvesLeBorg Mar 21 '18 at 15:19
  • Can you show your implementation of pack? and Why the result is not what you are looking for? – Starx Mar 21 '18 at 15:19
  • Possible duplicate: https://stackoverflow.com/a/2484315/1461181 – odan Mar 21 '18 at 15:20
  • 1
    @YvesLeBorg, :) I didn't know the indexing thing BTW. Thank you :) – Starx Mar 21 '18 at 15:20
  • Well the variations I've tried so far (that I remember) is: $dbToken = hex2bin(str_replace("-", "", $token)); $dbToken = pack("H*", str_replace("-", "", $token)); $db = str_replace("-", "", $token); $dbToken = hex2bin($db); – Johan Lundgren Mar 21 '18 at 15:21

2 Answers2

4

You can get the bytes from a Ramsey\Uuid\Uuid object like this:

$uuid = \Ramsey\Uuid\Uuid::uuid4();
$bytes = $uuid->getBytes();
odan
  • 4,757
  • 5
  • 20
  • 49
1

FWIW, this is what i do (MySQL context):

/**
 *
 * pack with H* to ensure compatibility with MySQL function UNHEX.
 *
 * @param string $stringGuid
 *
 * @return string 16 bytes long
 *
 * @ref https://stackoverflow.com/questions/2839037/php-mysql-storing-and-retrieving-uuids
 */
function stringGuidAsBinaryGuid($stringGuid)
{
    $binary = pack("H*" , str_replace('-' , '' , $stringGuid));
    return $binary;
}

function binaryGuidAsStringGuid($binaryGuid)
{
    $string = unpack("H*" , $binaryGuid);
    $string = preg_replace(
        "/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/" ,
        "$1-$2-$3-$4-$5" ,
        $string["1"]
    );
    return $string;
}

/***
 *
 * returns a valid GUID, v4 (string, 36 bytes)
 *
 * @link http://php.net/manual/en/function.com-create-guid.php
 *
 * @return string
 *
 */
function GUID()
{

    // prefer strong crypto variant

    if (function_exists('openssl_random_pseudo_bytes') === true) {
        $data    = openssl_random_pseudo_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);    // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);    // set bits 6-7 to 10
        return vsprintf('%s%s-%s-%s-%s-%s%s%s' , str_split(bin2hex($data) , 4));
    }

    return sprintf(
        '%04X%04X-%04X-%04X-%04X-%04X%04X%04X' ,
        mt_rand(0 , 65535) ,
        mt_rand(0 , 65535) ,
        mt_rand(0 , 65535) ,
        mt_rand(16384 , 20479) ,
        mt_rand(32768 , 49151) ,
        mt_rand(0 , 65535) ,
        mt_rand(0 , 65535) ,
        mt_rand(0 , 65535)
    );

}
YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48