2
votes

I'm in the process of migrating from Amazon S3 to Google Storage and I can't seem to get my credentials to work. Here's some sample code that I put together to test my credentials:

$client = new S3Client([
    'credentials' => [
        'key' => 'GOOGxxxxxxxxxxxxxxx',
        'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    ],
    'region' => 'US',
    'version' => 'latest',
    'endpoint' => 'https://storage.googleapis.com',
]);

try {
    $result = $client->putObject(array(
        'Bucket' => 'devtest',
        'Key' => 'test',
        'Body' => 'Hello world'
    ));

    echo $result['ObjectURL'];
} catch (\Aws\S3\Exception\S3Exception $e) {
    // The AWS error code (e.g., )
    echo $e->getAwsErrorCode() . "\n";
    // The bucket couldn't be created
    echo $e->getMessage() . "\n";
}

Here's what I get back:

InvalidSecurity Error executing "PutObject" on "https://storage.googleapis.com/devtest/test"; AWS HTTP error: Client error response [url] https://storage.googleapis.com/devtest/test [status code] 403 [reason phrase] Forbidden InvalidSecurity (client): The provided security credentials are not valid. - InvalidSecurityThe provided security credentials are not valid. Incorrect Authorization header

I've tried googling 100 different combinations of this issue and can't find anything. I have Interoperability enabled, at least I think I do since I don't think I can get the key/secret without it being enabled first. And I have the Google Storage API enabled.

Any help would be greatly appreciated.

Edit: here's the Authentication Header in case that helps:

AWS4-HMAC-SHA256 Credential=GOOGGUxxxxxxxxxxx/20150611/US/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=9c7de4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

I noticed it stays "aws4_request" even when I specify 'signature' => 'v2'. Not sure if that matters.

I took a look at the S3Client code and it doesn't use the 'signature' config key as far as I can tell. The only thing I found was 'signature_version' which when set to v2, I get this error:

Unable to resolve a signature for v2/s3/US. Valid signature versions include v4 and anonymous.

I'm using Laravel 5.1 with composer package aws/aws-sdk-php version 3.0.3

Any ideas?

1
To eliminate the possibility that the client code is somehow making valid credentials invalid, can you try using your key and secret in a gsutil config file, and see if you can perform gsutil operations with those credentials? Also, did you create your HMAC credentials this way? cloud.google.com/storage/docs/migrating#keysMike Schwartz
Perhaps signature => 'v2' in the constructor? Google doesn't seem to have implemented v4 and you might be defaulting to that. The wording of the error suggests an invalid format to the auth header, rather than a mismatched signature.Michael - sqlbot
@MikeSchwartz Yes, I created my credentials through the Interoperability. Yes, they work when I use gsutil. I can run "gsutil ls gs://devtest" and it properly lists the files in the bucket. I added some additional info to my post. Any help would be greatly appreciated.Citizen
@Michael-sqlbot I tried that but I don't think that config actually gets used anymore. I updated my post with more info about the Auth header.Citizen
I suspect this is something about the way that PHP SDK is producing the credentials on the wire. That error message happens when the credentials GCS receives are neither AWS nor GOOG1 credentials. I suggest running gsutil -D ls and looking at the Authorization header it sends; then capture the Authorization header the PHP SDK is sending, and compare them. I see gsutil sending credentials like: Authorization: GOOG1 GOOG<...>Mike Schwartz

1 Answers

2
votes

S3 only supports v4 signatures, and this requirement is enforced by the PHP SDK. It seems that Google Cloud Storage only supports v2 signing, so you wouldn't be able to use the same library to talk to both. Google does provide their own PHP SDK, which might make talking to Cloud Storage a bit easier.