zoukankan      html  css  js  c++  java
  • Oracle中使用hash_hmac() 函数报错问题/以及Oracle遇到Oauth1.0授权和oauth_signature生成规则

    最近在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 RightNowConnectCryptov1_4 as Crypto;  //这里引入
    
    try{
         $md = new CryptoMessageDigest();  
         $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 CryptoMessageDigest();
         $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);
      ps:注意千年大坑来了,卡了我两天的地方就在这里,官网文档如下: //}
    else { // $key = $key . str_repeat(chr(0x00), $size - strlen($key)); //}
      其实这里不需要eles
      $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;
      }
    或者
    function getSignature($key,$str)
    {
    $signature = "";
    if (function_exists('hash_hmac')) {
    $signature = base64_encode(hash_hmac("sha1", $str, $key, true));
    } else {
    $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).$str
    )
    )
    )
    );
    $signature = base64_encode($hmac);
    }
    return $signature;
    }
     

    坑②那就是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 =urlencode(base64_encode(hmacsha1($secret,$paramstring ))); //带入上面自定义加密函数,最后千万记得用urlencode 转义,不然概率报无效登入,切记!!!

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

    最后,其实在这个问题上我卡了好好几天,菜的抠脚,而且能找的文章少之又少。所以才写了这么一篇博客来希望后面的人能快速找到问题!如果对你有帮助的话,记得点个赞再走^_^!!!
  • 相关阅读:
    2018年3月至4月小结
    前端面试中,经常看到垂直居中与水平居中,实际排版用的多吗?
    Hbuilder配置识别逍遥安卓模拟器
    php静态变量与方法与phar的使用
    切面反射获取方法
    Spring:源码解读Spring IOC原理
    怎样批量提取JPG照片的文件名
    如何1秒批量提取电脑文件夹中的所有文件、文件夹名字到txt/excel
    用powermock 方法中new对象
    springboot单元测试自动回滚:@Transactional
  • 原文地址:https://www.cnblogs.com/yezi1116/p/15037621.html
Copyright © 2011-2022 走看看