Supplied key param cannot be coerced into a privat

2019-01-12 06:52发布

问题:

I'm trying to test this example that I found here so that I can do a direct upload on the client side without having the user login using Google Cloud Storage.

All of the constants expressed have their correct values, and the path is correct and does not have an empty contents.

The error I'm getting:

openssl_sign(): supplied key param cannot be coerced into a private key

My function implemented is:

public static function storageURL( $id, $method = 'GET', $duration = 10 ) {
    $key = file_get_contents(self::KEY_FILE);
    $pkey = openssl_get_privatekey($key, 'notasecret');
    $expires = time( ) + $duration;
    $content_type = ($method == 'PUT') ? 'application/x-www-form-urlencoded' : ''; 
    $to_sign = ($method . "\n" . 
    /* Content-MD5 */ "\n" . 
    $content_type . "\n" . 
    $expires . "\n" . 
    '/'.self::BUCKET_NAME.'/' . $id); 
    $signature = '*Signature will go here*';
    if (!openssl_sign( $to_sign, $signature, $pkey, 'sha256' ))
    { 
        error_log( 'openssl_sign failed!' );
        $signature = '<failed>'; 
    } else { 
        $signature = urlencode( base64_encode( $signature ) ); 
    } 
    return ('https://'.self::BUCKET_NAME.'.commondatastorage.googleapis.com/' .
        $id .
        '?GoogleAccessId=' . self::SERVICE_ACCOUNT_NAME .
        '&Expires=' . $expires . '&Signature=' . $signature);
    }

回答1:

First, you need to use openssl_pkcs12_read to read the key file, not file_get_contents. Second, I believe you want to leave off the second parameter to openssl_get_privatekey.

I highly recommend you use google-api-php-client for this, which has Google_P12Signer.php



回答2:

The safer way is to use Google_Signer_P12 class shipped with Google API PHP client to do that.

Code sample:

set_include_path(get_include_path() . PATH_SEPARATOR . 'PATH/TO/API/src');
require_once 'Google/Signer/P12.php';

$p12contents = file_get_contents('FILE.p12');
$googleSigner = new Google_Signer_P12($p12contents, 'notasecret');
$signature = $googleSigner->sign($data);