Background
I am trying to create a signed url to fetch a resource from AWS S3. There are several examples in aws s3 documentation , and as a first step I am trying to replicate the last example on that page.
My code is :
$access_key = "AKIAIOSFODNN7EXAMPLE";
$secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
$string_to_sign = "GET\n\n\n1175139620\n/johnsmith/photos/puppy.jpg";
$encode = hash_hmac('sha1', utf8_encode($string_to_sign) , $secret_key) ;
echo base64_encode($encode). "\r\n" ;
The above code outputs
MzY5ODAyOGU3MGYzYWNjZjk2MTczYTA0MzU3OWE5MzQzNTJjNGE3Zg==
According to the example, the result should be
NpgCjnDzrM%2BWFzoENXmpNDUsSn8%3D&
I do understand that the result needs to be url encoded , but I think I am still far off. Can I get some help please ?
I found the solution
$encode = hash_hmac('sha1', utf8_encode($string_to_sign), $secret_key);
is replaced by
$encode = hash_hmac('sha1', utf8_encode($string_to_sign), $secret_key, true );
Final script to simulate the example is :
$access_key = "AKIAIOSFODNN7EXAMPLE";
$secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
$string_to_sign = "GET\n\n\n1175139620\n/johnsmith/photos/puppy.jpg";
$encode = hash_hmac('sha1', utf8_encode($string_to_sign), $secret_key , true ) ;
echo urlencode(base64_encode($encode)) . "\r\n" ;
Related
I have the following decrypted message, which has previously been encrypted using AES-256-CBC
240dcbefc0f82fadc00ef8494488aaa81400000c2def01e79fec6c4d9a822358dd8a910cac606e8afcb607793cb442093a56b7b40b0b0b0b0b0b0b0b0b0b0b0b
I derive the following 20 BYTE HMAC from this message:
dd8a910cac606e8afcb607793cb442093a56b7b4
My goal is to re-create this HMAC using PHP, I attempt with the following code:
$iv = hex2bin('240dcbefc0f82fadc00ef8494488aaa8'); // random iv - first 16 bytes of the message
$message = hex2bin('1400000c2def01e79fec6c4d9a822358'); // the actual message being decrypted - next 16 bytes
$key = hex2bin('b109124b62e2c8b8248e9865990325fddcc61143'); // encryption key
$hmac = hash_hmac('sha1', $iv.$message, $key);
print($hmac); // 03634ba3f4a0c854a0b791d27f331ecdfad1e87e
$attempt2 = hash('sha256', $iv.$message, true);
$hmac = hash_hmac('sha1', $attempt2, $key);
print($hmac); // 39ad1fb94ab251cdaf3f21cf8673e070733f4e16
I know I'm missing something but I'm struggling to understand the HMAC process as it's very confusing to me. Any help or advise is appreciated, thanks.
I found a solution on a random blog post online :D
here is what worked for me:
function check_mac($seq, $type, $msg, $key) {
$SequenceNumber = pack("NN", 0, $seq);
$Type = pack("Cnn", $type, 0x0303, strlen($msg));
$data = $SequenceNumber . $Type . $msg;
$calculated_mac = hash_hmac("sha1", $data, $key, true);
print(bin2hex($calculated_mac) . "\n");
}
Also, the IV does not need to be included, just the message by itself as the $msg variable
Blog Post:
https://adayinthelifeof.nl/2013/12/30/decoding-tls-with-php/
I have to do a native JWT Key Method, and i have to use RSA256 method, but when i try this :
$getPrivate = openssl_pkey_get_private(".../rsa_private.pem", $passphrase);
openssl_sign($data, $partialSignature, $getPrivate, sha256WithRSAEncryption);
$signature .= $partialSignature;
$function_rsa = base64_encode($signature);
or that
$encrypt_rsa = openssl_private_encrypt($data, $partialEncrypted, $privateKey, OPENSSL_PKCS1_PADDING);
$encrypted .= $partialEncrypted;
$function_rsa = base64_encode($encrypted);
it won't work correctly, it return me that for the case 1 :
F/BXtAkMLK7W/2wGw2Gi/s1XT+2UphCafVug/oa/OQ62IXwblaS7vVyx5jyB1HTNMz/hlTGmr0ukj3J9lyDAunbP/2nmgWOGMjv2o52WGGaoVsLfJHPyrp7uLuYsq3VrLnnMRyaIrfSw/au2kiVX4HUhvBFOd5GHiRqXSfMiRqd4sj+DLSLlMMSw+LtyWWhlX1Sr4pcTFqa9EDrwdDuhpTWoagTVQP/4FTLl2pncd/zZso5MB+tjX72T/YjUnBuQyPqtjQPDiNMgm+M4lz6d3GZZvOHV05gWXr+aTgCAnTKPje8DBwNFLs5XgBIascUqRVz1k1v8n7B8lRxg1yOlqg==
or that for the case 2 :
e0Gm+MnmGvpFXhNDoj0Vsdl+1v+xxqW7uFFLBeGTjrcAr+ON7CadR0KFQ6lffEiZ17PAA584gDdLOtvpOH3q8V1UIqhbLQhJwEPstkBZRMNsplJse+eBsHNPnev2JYBDABbnAhE7I+xM9mI8iTCjW0DTcAecXahN+UctzBlKveZBMOcnJsRhgfYGZ7SKPySysIc6QoTkiNEJCgb68S8mfsiX9KSDgCwfc50Rql2nKEc15nO83OtkFvuLAjGxsQdSytzQ3hUuLXKqvEqeZsIgYYwQwbKWpLlJuFFQWL3VyjhupnBIO0tDRbZ/Lhqr62DhAoWkKjFtQiHdGdDv407xPQ==
I have correct privateKey.
Can you guys help me ? Thank you :)
I'm trying to setup an app to sign with my URLs so they may authenticate but I can't seem to figure out how to replicate the code that I'm trying from the following page: https://help.sendowl.com/help/signed-urls#example
order_id=12345&buyer_name=Test+Man&buyer_email=test%40test.com&product_id=123&signature=QpIEZjEmEMZV%2FHYtinoOj5bqAFw%3D
buyer_email=test#test.com&buyer_name=Test Man&order_id=12345&product_id=123
buyer_email=test#test.com&buyer_name=Test Man&order_id=12345&product_id=123&secret=t0ps3cr3t
publicStr&t0ps3cr3t
This is the steps:
First order the parameters (removing the signature) and unescape
them:
Next append your Signing secret:
Generate the key to sign with:
Perform the HMAC-SHA1 digest with Base 64 encode: QpIEZjEmEMZV/HYtinoOj5bqAFw=
The following is what I tried but end up not getting the same result:
$signKey = "t0ps3cr3t";
$signData = "buyer_email=test#test.com&buyer_name=Test Man&order_id=12345&product_id=123&secret=t0ps3cr3t";
$passData = hash_hmac("sha1", $signData, base64_decode(strtr($signKey)), true);
$passData = base64_encode($passData);
echo $passData;
I keep getting x8NXmAmkNBPYCXwtj65mdVJ8lPc=
I was able to replicate with the following: took me a bit to figure out something so simple.. been coding for 11 hours straight.
Thanks.
$data = "buyer_email=test#test.com&buyer_name=Test Man&order_id=12345&product_id=123&secret=t0ps3cr3t";
$key = "publicStr&t0ps3cr3t";
$pass1 = hash_hmac('sha1', $data, $key, true);
$pass = base64_encode($pass1);
echo $pass;
$pass will return "QpIEZjEmEMZV/HYtinoOj5bqAFw=", the correct value.
$current_timestamp = Carbon::now()->timestamp;
$signstring = "z001-line-anime-gif." . $current_timestamp . ".aaaabbbbccccdddd";
$secret = 'STG-7f*(:hsM-1_eQ_ZD175QgEoJhI$:oR.zEQ<z';
$sig = hash_hmac('sha1', $signstring, $secret);
$signature = hex2bin($sig);
$signature = base64_encode($signature);
return $signature;
I have the PHP application integrated with Dropbox API. It worked good but since some time ago it stopped to work with non-latin symbols.
For example, if i try to create a dropbox folder with the API and use Cyrillic letters in folder name then API requests fail with error {"error": "Unauthorized"}
I have the PHP function
function createOAuthSignature($apiurl, $params, $oauth_secret, $oauth_token_secret, $method='GET'){
$urlencoded_apiurl = urlencode($apiurl);
$urlencoded_params = urlencode($params);
$basestring = $method .'&'.$urlencoded_apiurl.'&'.$urlencoded_params;
$oauth_signature = base64_encode(hash_hmac('sha1', $basestring, $oauth_secret.'&'.$oauth_token_secret, true));
$oauth_signature = urlencode($oauth_signature);
return $oauth_signature;
}
And the calling code is
$fullname = $parent . $foldername;
$fullnameEnc = rawurlencode($fullname);
$apiurl = $this->api_url .'fileops/create_folder/';
$params = 'oauth_consumer_key='.$this->oauth_consumer_key
.'&oauth_nonce='. $this->createNonce()
.'&oauth_signature_method=HMAC-SHA1'
.'&oauth_timestamp='. time()
.'&oauth_token='.$oauth_token
.'&oauth_version=1.0'
.'&path='. $fullnameEnc
.'&root=dropbox';
$oauth_signature = $this->createOAuthSignature($apiurl, $params, $this->oauth_secret, $oauth_token_secret);
$params .= '&oauth_signature='.$oauth_signature;
$action = $apiurl .'?'. $params;
$s = $this->curl->get($action);
What can be the problem there? I presume it is related to signature generating. But what is wrong there? This code worked fine just couple weeks ago.
Thanks
As Greg mentioned in a comment above, we're investigating, but if you want to switch to PLAINTEXT signing, it's quite easy. Change createOAuthSignature to just do this:
function createOAuthSignature($apiurl, $params, $oauth_secret, $oauth_token_secret, $method='GET'){
return urlencode($oauth_secret.'&'.$oauth_token_secret);
}
And in the calling code, change the signature method to PLAINTEXT:
$params = ...
.'&oauth_signature_method=PLAINTEXT'
...
I have looked at most samples of code based on this issue on stack overflow but I still cant get the request to work. I keep getting this error:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Here is my code:
$access_key = "ACCESS_KEY";
$associateTag = "AOSSOCIATE_TAG";
$secretkey = "SECRET_KEY";
$keywords = "harry%20potter";
$timestamp = gmdate("Y-m-d\TH:i:s\Z");
$operation = "AWSECommerceService";
function createSignature($operation,$timestamp,$secretkey){
$the_string=$operation.$timestamp;
return base64_encode(hash_hmac("sha256",$the_string,$secretkey,true));
}
$signature = createSignature ($operation,$timestamp,$secretkey);
$APIcall =
"http://ecs.amazonaws.com/onca/xml?".
"AWSAccessKeyId=$access_key&".
"AssociateTag=$associateTag&".
"BrowseNode=1000&".
"ItemPage=1&".
"Keywords=$keywords&".
"Operation=ItemSearch&".
"ResponseGroup=Medium&".
"SearchIndex=Books&".
"Service=AWSECommerceService&".
"Timestamp=$timestamp&".
"Version=2011-08-01&".
"Signature=$signature";
$response = simplexml_load_file($APIcall);
Can anyone help?
I had this issue long time and it worked for me with this code :
require_once 'Crypt/HMAC.php';
require_once 'HTTP/Request.php';
$keyId = "adasdasd";
$secretKey = "asdasdasdasdasd+";
function hex2b64($str) {
$raw = '';
for ($i=0; $i < strlen($str); $i+=2) {
$raw .= chr(hexdec(substr($str, $i, 2)));
}
return base64_encode($raw);
}
function constructSig($str) {
global $secretKey;
$str = utf8_encode($str);
$secretKey = utf8_encode($secretKey);
$hasher =& new Crypt_HMAC($secretKey, "sha1");
$signature = hex2b64($hasher->hash($str));
return ($signature);
}
$expire = time()+1000;
$resource = "/demo/files/clouds.jpg";
$date = gmdate("D, d M Y G:i:s T");
$mime = "image/jpeg";
$stringToSign = "PUT\n";
$stringToSign .= "\n";
$stringToSign .= "$mime\n";
$stringToSign .= "$date\n";
$stringToSign .= $resource;
$req =& new HTTP_Request("http://nameofmine.s3.amazonaws.com/files/clouds.jpg");
$req->setMethod("PUT");
$req->addHeader("Date",$date);
$req->addHeader("Authorization", "AWS " . $keyId . ":" . constructSig($stringToSign));
$req->addHeader("Content-Type",$mime);
$req->setBody(file_get_contents($file_path));
$req->sendRequest();
$responseCode = $req->getResponseCode();
$responseString = $req->getResponseBody();
echo $responseCode;
As you see you have to use Crypto, HTTP pear plugins
The function seems ok (it is the same as the one used in amazon AWS SDK) so make sure that there is no whitespace in front or after the copied key.
When I typed in my credentials by hand, I got the same error a couple of times.
Then I tried Console for Windows so I could copy/paste my credentials. This removed the error message. Either I sucked at typing, or sucked at reading.
Long story short: Don't type by hand, copy and past credentials to avoid typos.
EDIT:
My problem was when trying to add my credentials via EB CLIx3.