USING RAW PUBLIC KEYS IN PHP

Now here we are going to write some stuff and it is going to be about the what it is like supporting PHP.

// this function makes up for the fact that openssl doesn't
// currently support direct use of modulus and exponent except
// when PEM encoded in publicKeyInfo or Certificate ASN.1 
// So, believe it or not, I convert it into a publicKeyInfo ASN
// structure and then turn it into PEM - then it works fine.

function kimssl_pkey_get_public ($modulus, $exponent)
{
    // decode to binary
    $modulus = base64_decode($modulus);
    $exponent = base64_decode($exponent);

    // make an ASN publicKeyInfo
    $exponentEncoding = makeAsnSegment(0x02, $exponent);    
    $modulusEncoding = makeAsnSegment(0x02, $modulus);    
    $sequenceEncoding = makeAsnSegment(0x30, 
        $modulusEncoding.$exponentEncoding);
    $bitstringEncoding = makeAsnSegment(0x03, $sequenceEncoding);
    $rsaAlgorithmIdentifier = pack("H*", "300D06092A864886F70D0101010500"); 
    $publicKeyInfo = makeAsnSegment (0x30, 
        $rsaAlgorithmIdentifier.$bitstringEncoding);

    // encode the publicKeyInfo in base64 and add PEM brackets
    $publicKeyInfoBase64 = base64_encode($publicKeyInfo);    
    $encoding = "-----BEGIN PUBLIC KEY-----\n";
    $offset = 0;
    while ($segment=substr($publicKeyInfoBase64, $offset, 64)){
       $encoding = $encoding.$segment."\n";
       $offset += 64;
    }
    $encoding = $encoding."-----END PUBLIC KEY-----\n";

    // use the PEM version of the key to get a key handle
    $publicKey = openssl_pkey_get_public ($encoding);

    return ($publicKey);
}

// this helper function is necessary because PHP's openssl
// currently requires that the public key be in PEM format
// This does the ASN.1 type and length encoding

function makeAsnSegment($type, $string)
{
    // fix up integers and bitstrings
    switch ($type){
        case 0x02:
            if (ord($string) > 0x7f)
                $string = chr(0).$string;
            break;
        case 0x03:
            $string = chr(0).$string;
            break;
    }

    $length = strlen($string);

    if ($length < 128){
       $output = sprintf("%c%c%s", $type, $length, $string);
    }
    else if ($length < 0x0100){
       $output = sprintf("%c%c%c%s", $type, 0x81, $length, $string);
    }
    else if ($length < 0x010000) {
       $output = sprintf("%c%c%c%c%s", $type, 0x82, $length/0x0100, $length%0x0100, $string);
    }
    else {
        $output = NULL;
    }

    return($output);
}

Truth is stranger than fiction.

Published by

Kim Cameron

Work on identity.