最近在Oracle上發現使用hash_hmac()報找不到此函式。為此特意查到oracle的文件。詳細請看官網回答:https://cx.rightnow.com/app/answers/detail/a_id/9825/~/cannot-use-the-hash_hmac-function-in-php

原因是:此擴充套件在 Oracle B2C 服務中未啟用,無法啟用。就很無語。但是它家自己推出個  Crypto API 也是加密的一個類

下面是 sha256 簡單是例子:

oracle雲api直通車:https://documentation.custhelp.com/euf/assets/devdocs/cloud21a/Connect_PHP/Default.htm  裡面 有詳細的  Crypto API 介紹

<?php

/**************Agent Authentication**************/
require_once(get_cfg_var("doc_root") . "/ConnectPHP/Connect_init.php" );
initConnectAPI("admin", "adminpwd"); /******Use the “Crypto” versioned namespace*********/
use RightNow\Connect\Crypto\v1_4 as Crypto; //這裡引入 try{
$md = new Crypto\MessageDigest();
$md->Algorithm->ID = 3; //SHA256
$md->Text = "This is a message to be digested using SHA256";
echo "Data : " .$md->Text . "<br>";
$md->hash();
$hashed_text = $md->HashText;
echo "Output : " .bin2Hex($hashed_text)."<br>";
}
catch (Exception $err ){
echo $err->getMessage();
}
?>

坑①:預設情況下,Crypto API 的 SHA-256 API 沒有實現金鑰。為了獲得與 PHP 的 HASH_HMAC 相同的功能,但是官網給出瞭解決辦法。

可以使用以下程式碼在 PHP 中複製此功能:

/*
The sample code in this document or accessed through this document is not
certified or supported by Oracle. It is intended for educational or testing
purposes only. Use of this sample code implies acceptance of the License Agreement
at https://www.oracle.com/downloads/licenses/standard-license.html .
*/ function standard_crypt($msg){
try{
$md = new Crypto\MessageDigest();
$md->Algorithm->ID = 3; // SHA-256
$md->Text = $msg;
$md->hash();
$hashed_text = $md->HashText;
return ($hashed_text);
} catch (Exception $err ){
echo $err->getMessage();
}
}
// Create Signature Hash
function custom_hmac($algo, $data, $key)
{
$size = 64;
$pack = chr(0x00);
if (strlen($key) > $size) {
$key = $algo($key);
} else {
$key = $key . str_repeat(chr(0x00), $size - strlen($key));
}
// Outter and Inner pad
$opad = str_repeat(chr(0x5C), $size);
$ipad = str_repeat(chr(0x36), $size); $k_ipad = $ipad ^ $key;
$k_opad = $opad ^ $key; return $algo($k_opad.$algo($k_ipad.$data));
} $data = "foo";
$secret = "bar";
$bin_hash = custom_hmac('standard_crypt', $data, $secret, false);
echo "HASH: ".bin2hex($bin_hash); //最後從二進位制轉換成十六進位制,但是一般需要的是 base64_encode(),把bin2hex替換就好。

但是我自己也找到了實現祕鑰加密的方法,更為簡單 (個人推薦這種)並且本人測試過和 php原函式 hash_hmac() 加密效果一樣!

 function oauth_hmacsha1($key, $data) {
return base64_encode(hmacsha1($key, $data));
  }
function hmacsha1($key,$data) {
$blocksize=64;
$hashfunc='sha1';
if (strlen($key)>$blocksize)
$key=pack('H*', $hashfunc($key));
$key=str_pad($key,$blocksize,chr(0x00));
$ipad=str_repeat(chr(0x36),$blocksize);
$opad=str_repeat(chr(0x5c),$blocksize);
$hmac = pack(
'H*',$hashfunc(
($key^$opad).pack(
'H*',$hashfunc(
($key^$ipad).$data
)
)
)
);
return $hmac;
}

坑②:那就是oauth1.0的 oauth_signature 的生成規則 (這裡用的sha1加密)其它也類似

  重點1:源串由3部分內容用“&”拼接起來

  HTTP請求方式(對應 GET | POST ) & urlencode(uri) & urlencode(a=x&b=y&...)

  示例程式碼:

  

  ps:重點中的重點來了!!!!

    post:GET | POST 一定要大寫;

    uri也就是例中 $cur: url也就是你的傳送請求的 例如:https://5035664-sb2.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=456&deploy=1

    如果請求後面 ?號是攜帶引數的 script=456&deploy=1像這樣的,千萬記得 $cur 的值不需要加上引數  https://5035664-sb2.restlets.api.netsuite.com/app/site/hosting/restlet.nl 這樣就行。

    script=456&deploy=1 需要放到下面 $paramstring 進行拼接。

    $paramstring :就是 oauth_version=1.0&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1299143758&oauth_nonce=1606024431&oauth_consumer_key=200001。

    ps:$paramstring 拼接的話是一定要按照字典排序從低到高的(切記 !)沒有額外引數的話就不用 加上,以  oauth_consumer_key 開頭那樣!

$paramstring = "deploy=1&oauth_consumer_key=" . $oauth_consumer_key . "&oauth_nonce=" . $oauth_nonce . "&oauth_signature_method=HMAC-SHA1" . "&oauth_timestamp=" . $oauth_timestamp . "&oauth_token=" . $oauth_token ."&oauth_version=1.0&script=456";

//金鑰
$secret = urlencode($oauth_consumer_secret) ."&".urlencode($oauth_token_secret);

$oauth_signature = base64_encode(hmacsha1($secret,$paramstring )); //帶入上面自定義加密函式

以上就是生成 $oauth_signature 的注意事項了!

最後,其實在這個問題上我卡了好好幾天,菜的摳腳,而且能找的文章少之又少。所以才寫了這麼一篇部落格來希望後面的人能快速找到問題!如果對你有幫助的話,記得點個贊再走^_^!!!