【问题标题】:How to get the key ID value in a JWK response (PHP)如何在 JWK 响应 (PHP) 中获取密钥 ID 值
【发布时间】:2020-05-13 12:40:21
【问题描述】:

我正在服务器端生成一个公钥以传递到客户端以呈现 iframe(由第三方托管)。

我从 JWK 响应中获取了大量数据,但我只需要 keyID 值。

{ “数据”: “{\” KEYID \ “:\” eyJraWQiOiIzZyIsImFsZyI6IlJTMjU2In0.eyJmbHgiOnsicGF0aCI6Ii9mbGV4L3YxL3Rva2Vucz9mb3JtYXRcdTAwM2RKV0UiLCJkYXRhIjoiOFZ6WnhyUHd2b1dRb1I0QTVTRWNteEFBRUliNlJsT1YzdGU4UUxGdmEwb08wTEliWkhtWmE4Z2ZqT0lSWklmS1FaUElRYmhaZHVlRFNwQzZZZllUanF0cU94d2xtUVlQa1FzZUcrL05WUGlBbUZUdGtUNjlUbXAyb3pEOWJqT0NyVFlQIiwib3JpZ2luIjoiaHR0cHM6Ly90ZXN0ZmxleC5jeWJlcnNvdXJjZS5jb20iLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJ1c2UiOiJlbmMiLCJuIjoiaGNLRlU5UllCR0VwY1JyR3FQQ2J1U3BlOFdyeTRRUUNvMUdiRml4ZHdWMUtuN09BMHQtRDdXM2tvUjN6MDc3UndnYnBldTdvbV8xd0ZrRjVRLTBNeVNfdzk3TklmaVk1OVNLb3JqdWhfQmt2NHdJVGVUbm9LN2ZROHJyOTJSOUNKTFp6UFdlUVJPMDVxeWxiLVdVWUJvOU5sa2QwZHl6b2RlbEoxWVRzQ1JzYlRVc0ZRMUxKZHVIWWw0X3kzTF9FbnkwaG1mSFg5cll4U2ozamhmZVpZYVhYa0wtdERCa2k5VF9zXzhzb19RQjNLN29oR2tqSDU1TUQwRkdDNzVpRS1UcmtqNFd0cWNyYjI3S3BNSzdXWm1qSnJUMFE0bzlMMTBURXJvZE1HeEpfTm5IMGdSYmUwTFVSOWhaVnUzMG9tWkdrQVhfQXhUa1VJWktXQzZENkJ3Iiwia2lkIjoiMDd1SlMwT0dpR2pObzF6ejRTbGFpZUIzQkprSWc1bVAifX0sImN0eCI6W3siZGF0YSI6eyJ0YXJnZXRPcmlnaW5zIjpbImh0dH A6Ly9sb2NhbGhvc3Q6ODA4MiJdLCJtZk9yaWdpbiI6Imh0dHBzOi8vdGVzdGZsZXguY3liZXJzb3VyY2UuY29tIn0sInR5cGUiOiJtZi0wLjExLjAifV0sImlzcyI6IkZsZXggQVBJIiwiZXhwIjoxNTgwMTg5NDA2LCJpYXQiOjE1ODAxODg1MDYsImp0aSI6InNYYWNWSm43bkI1a1ZvSnIifQ.Hr-DwfFv-90bBtUWhACXwkhVFefh7fNOV9FS5Epu5fcL7Ji_pE9GHQIhaX5F31VM-EAOz55gG0eYnEu7ZAptR1mq3WgxNx3Af9ngKpbl4ZTb9cUxjGf3DdGJ1-J26aziJx3GcaZREfFyabDWbThyKlGTxSbnGHb7-UcQ_MPmh-znt_691y_gX9Qo8fe6XeJw8-Ir4XwwznjNLa31-EctYfnYUbfOnjR_8rfuFNnulvQecHs1e4zFVVAqm8mqex-umdlPbPUGT8xzYN-G0oLMdj3uMAAeSuyrdAifVXWSXyyyBHU5rIp-8anGWj_9RQrwvOH7MOIerV3Lej1-lEOxTw \ “\ ”明镜\“:空,\ ”JWK \“:空}” }

我需要 keyID 值并将其传递给客户端的一个名为“captureContext”的变量。

这是我的客户端代码,但它向我返回了上面的所有数据:

var captureContext = <?php echo json_encode($body)?>;
console.log(captureContext);

这就是我在服务器端生成公钥的方式:

<?php

define ('HMAC_SHA256', 'HmacSHA256');

//Step 0.  Set Secret Key a
define ('SHARED_SECRET_KEY', '--insert shared secret--');
define ('KEY_ID','--insert key ID--');
define ('MERCHANT_ID','--insert merchant ID--');

define('TARGET_ORIGIN',"http://localhost:8082");
define ('SECURE_HTTPS','https://');
define('HOST','apitest.cybersource.com');
define('DESTINATION_RESOURCE','flex/v1/keys?format=JWT'); 

define('SHA256','sha256');
define('ENCRYPTION_TYPE','RsaOaep256');


function loggingHelper( $response, $curl, $testInfo, $requestBody ) {
        printf("%s\n",$testInfo);
        if(!$response) {
            printf ('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
        } else {
            if (empty($requestBody) == false && $requestBody != '') {
                $json = json_decode($requestBody);
                $json = json_encode($json, JSON_PRETTY_PRINT);
                printf("Request Body : %s\n", $json);
            }
            $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
            $header = substr($response, 0, $header_size);
            $body = substr($response, $header_size);
            printf ("Response Status: %s\n",curl_getinfo($curl, CURLINFO_HTTP_CODE));
            printf($header);
            if (empty($body) == false && $body != '') {
                $json = json_decode($body);
                $json = json_encode($json, JSON_PRETTY_PRINT);
                printf("Response Body : %s\n", $json);
            }

        }
    }

function getSignature($params){
       return signData(buildDataStringToSign($params), SHARED_SECRET_KEY); 

}

function getHeadersString($params) {


   $headerStringArray = array();
   foreach($params as $field => $value){
        $headerStringArray[] = $field;
    } 
    return implode(" ",$headerStringArray);
}

function buildDataStringToSign($params) {
        $dataStringArray = array();

        foreach ($params as $field => $value) {
           $dataStringArray[] = $field . ": " . $value;
        }
        return implode("\n",$dataStringArray);
}

function jdebug($variable,$text){

    echo "<br>=====".$text."=====<br>";


    var_dump($variable);

    echo "<br>=====".$text."=====<br>";


}


function signData($data, $secretKey) {
    //Remember, the key is provided in a base64 format, so it must be decoded before using in the hmac

    return base64_encode(hash_hmac(SHA256, $data, base64_decode($secretKey),true));

}


function commaSeparate ($dataToSign) {
    return implode(",",$dataToSign);
}

function getServerTime() {

     return gmdate("D, d M Y H:i:s \G\M\T");
 }

function getDigestHeader($params) {

    return "SHA-256=".base64_encode(hash(SHA256,$params,true));

}

function getDigestBody() {

      $digestBody = Array("encryptionType" => ENCRYPTION_TYPE,
                          "targetOrigin" => TARGET_ORIGIN );

    //return  "{\n  \"encryptionType\": \"".ENCRYPTION_TYPE."\",\n  \"targetOrigin\": \"".TARGET_ORIGIN."\"\n}";
    return  json_encode($digestBody);

}

    $digestBody = getDigestBody();

    $digestHash = getDigestHeader($digestBody);

    $serverTime = getServerTime();


    $signedHeaders['host'] = HOST;
    $signedHeaders['date'] = $serverTime;

    $signedHeaders['(request-target)'] = 'post /'.DESTINATION_RESOURCE;
    $signedHeaders['digest'] = $digestHash;


    $signedHeaders['v-c-merchant-id'] = MERCHANT_ID;


    $signature = getSignature($signedHeaders);


   $signatureHeader = "";

   $signatureHeader.="keyid=\"".KEY_ID."\"".", ";
   $signatureHeader.="algorithm=\"".HMAC_SHA256."\"".", ";
   $signatureHeader.="headers=\"".getHeadersString($signedHeaders)."\"".", ";
   $signatureHeader.="signature=\"".$signature."\"";

        $curl = curl_init ();

        $headers = array("host: ".$signedHeaders['host'],
                          "date: ".$signedHeaders['date'],
                          "digest: ".$signedHeaders['digest'],
                          "signature: ".$signatureHeader,
                          "Content-Type: application/json; charset=utf-8",
                          "v-c-merchant-id: ".$signedHeaders['v-c-merchant-id']);

        $absUrl = SECURE_HTTPS.HOST."/".DESTINATION_RESOURCE;


        $opts = array ();

        $opts [CURLOPT_POST] = 1;
        $opts [CURLOPT_POSTFIELDS] = $digestBody;
        $opts [CURLOPT_PROTOCOLS] = CURLPROTO_HTTPS;
        $opts [CURLOPT_SSLVERSION] = CURL_SSLVERSION_TLSv1_2;
        $opts [CURLOPT_URL] = $absUrl;
        $opts [CURLOPT_RETURNTRANSFER] = true;
        $opts [CURLOPT_CONNECTTIMEOUT] = 50;
        $opts [CURLOPT_TIMEOUT] = 100;
        $opts [CURLOPT_HTTPHEADER] = $headers;
        $opts [CURLOPT_HEADER] = 1;


        curl_setopt_array ( $curl, $opts );

        $response = curl_exec ( $curl );


        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);


        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $header = substr($response, 0, $header_size);
        $body = substr($response, $header_size);


        $response = json_decode($body);
        $jwk = $response->jwk;


        curl_close ( $curl );

?>

希望你能帮帮我!先感谢您!

【问题讨论】:

  • 我的天啊,我去年放弃了这个,但不得不再做一次,我没有看到你的答案,但这就是我正在寻找的答案~~非常感谢,抱歉来晚了! :D @jasie

标签: javascript php html json jwk


【解决方案1】:

我已尽力理解您粘贴的代码,但很难说响应是如何从服务器生成/响应的,因为从我对代码的扫描来看,没有迹象表明第一部分代码和第二部分都在服务器端,或者第一部分是客户端的测试代码(第一部分显然是与php混合的代码,例如js + php)。

所以有两种可能:

  1. 两个代码都在服务器端
  2. 只有第二个代码在服务器端

1:如果代码的第一部分在服务器端并且正在从客户端请求,并且您想要拆分结果并只发送回密钥,那么您需要做的就是:

// if $body is an array in php
var captureContext = <?php echo $body['data']['keyId'] ?>;

// if $body is an object in php
var captureContext = <?php echo $body->data->keyId ?>;

2:如果第一部分应该是客户端,这意味着第二部分中的某处将数据响应回客户端请求(通常带有echo),那么您需要找到响应数据载体(例如$response 在第二部分)然后做:

# if $response is the final response data carrier/variable
echo $response->data->keyId;

如果代码的第一部分是客户端应该获取的内容,并且您询问如何从整个响应数据中拆分密钥:

var captureContext = <?php echo json_encode($body)?>;
var resp = JSON.parse(captureContext);
var keyID = resp.data.keyId;
console.log(keyID);

如果这仍然给你一个错误 undefined 到 keyId,试试:

var captureContext = <?php echo json_encode($body)?>;
var resp = JSON.parse(captureContext);
var respData = JSON.parse(resp.data);
var keyID = respData.keyId;
console.log(keyID);

出现此类错误的原因是因为我注意到您在 console.log() 中的 JWK 帖子以不同的符号 "\" 显示了数据和 keyId,以及整个data 值是字符串格式,因此您可能需要为另一个内部 JSON 结构翻译两次。

根据我的猜测,第一个代码和第二个代码共享变量名,如果 $body 是同一个变量,那么将 keyId 从 JSON 格式拆分是一个非常简单的过程。

【讨论】:

  • 对不起,我不够清楚。但你是对的,第一个代码来自客户端,第二个代码来自服务器端。是的,他们正在共享包含上述 JWK 响应的变量名称 $body。我尝试了这段代码,但我没有在控制台日志中看到它们的 keyID 值,我仍然无法呈现 iframe。 ``` var captureContext = ; var resp = JSON.parse(captureContext); var keyID = resp.keyId;控制台.log(keyID); ```谢谢你的回复!
  • 对不起,代码keyID的最后一部分是我的错误,这是因为你在属性data下有它。再次检查,我已经编辑并修复了它。但是,如果对客户端的响应应该只包含 keyID 而不是完整的 JWK 数据,出于安全原因,最好的方法仍然是将该 ID 从服务器端的整个 JWK 中拆分出来。但是,我猜 JWK 是您尝试发送回客户端的正确 API。
  • 顺便说一句,还有一个不清楚的部分可能会导致错误,您为JWK粘贴的数据以{“data”:...}开头,后面的值为{“\ keyId"\: "\..."\ }。请注意,console.log() 可能会输出您发布的 JWK 之类的对象。
  • 嗯,我尝试了上面的两个代码,但控制台日志中没有返回 keyID 值,并且 iframe 仍然无法呈现。如何在服务器端从整个 JWK 中拆分 keyID?我在下面尝试过,但我有未定义的索引:数据并且我收到了一个空的 JWK 响应。 $body = json_decode($body, true); $body = json_decode($body['data']['keyId'], true); $keyId = $body['keyId'];另外,如果这是服务器端的代码,我应该如何在客户端指定它?谢谢!
  • 你能尝试以下步骤并给我输出,以便我可以告诉你关键在哪里:a)console.log(captureContext); b)console.log(JSON.parse(captureContext)); c)console.log(JSON.parse(captureContext).data); d)@987654338 @e) console.log(JSON.parse(JSON.parse(captureContext).data).keyId);
【解决方案2】:

我尝试了一些东西,我想我明白了:

$body = '{ "data": "{\"keyId\":\"eyJraWQiOiIzZyIsImFsZyI6IlJTMjU2In0.eyJmbHgiOnsicGF0aCI6Ii9mbGV4L3YxL3Rva2Vucz9mb3JtYXRcdTAwM2RKV0UiLCJkYXRhIjoiOFZ6WnhyUHd2b1dRb1I0QTVTRWNteEFBRUliNlJsT1YzdGU4UUxGdmEwb08wTEliWkhtWmE4Z2ZqT0lSWklmS1FaUElRYmhaZHVlRFNwQzZZZllUanF0cU94d2xtUVlQa1FzZUcrL05WUGlBbUZUdGtUNjlUbXAyb3pEOWJqT0NyVFlQIiwib3JpZ2luIjoiaHR0cHM6Ly90ZXN0ZmxleC5jeWJlcnNvdXJjZS5jb20iLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJ1c2UiOiJlbmMiLCJuIjoiaGNLRlU5UllCR0VwY1JyR3FQQ2J1U3BlOFdyeTRRUUNvMUdiRml4ZHdWMUtuN09BMHQtRDdXM2tvUjN6MDc3UndnYnBldTdvbV8xd0ZrRjVRLTBNeVNfdzk3TklmaVk1OVNLb3JqdWhfQmt2NHdJVGVUbm9LN2ZROHJyOTJSOUNKTFp6UFdlUVJPMDVxeWxiLVdVWUJvOU5sa2QwZHl6b2RlbEoxWVRzQ1JzYlRVc0ZRMUxKZHVIWWw0X3kzTF9FbnkwaG1mSFg5cll4U2ozamhmZVpZYVhYa0wtdERCa2k5VF9zXzhzb19RQjNLN29oR2tqSDU1TUQwRkdDNzVpRS1UcmtqNFd0cWNyYjI3S3BNSzdXWm1qSnJUMFE0bzlMMTBURXJvZE1HeEpfTm5IMGdSYmUwTFVSOWhaVnUzMG9tWkdrQVhfQXhUa1VJWktXQzZENkJ3Iiwia2lkIjoiMDd1SlMwT0dpR2pObzF6ejRTbGFpZUIzQkprSWc1bVAifX0sImN0eCI6W3siZGF0YSI6eyJ0YXJnZXRPcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MiJdLCJtZk9yaWdpbiI6Imh0dHBzOi8vdGVzdGZsZXguY3liZXJzb3VyY2UuY29tIn0sInR5cGUiOiJtZi0wLjExLjAifV0sImlzcyI6IkZsZXggQVBJIiwiZXhwIjoxNTgwMTg5NDA2LCJpYXQiOjE1ODAxODg1MDYsImp0aSI6InNYYWNWSm43bkI1a1ZvSnIifQ.Hr-DwfFv-90bBtUWhACXwkhVFefh7fNOV9FS5Epu5fcL7Ji_pE9GHQIhaX5F31VM-EAOz55gG0eYnEu7ZAptR1mq3WgxNx3Af9ngKpbl4ZTb9cUxjGf3DdGJ1-J26aziJx3GcaZREfFyabDWbThyKlGTxSbnGHb7-UcQ_MPmh-znt_691y_gX9Qo8fe6XeJw8-Ir4XwwznjNLa31-EctYfnYUbfOnjR_8rfuFNnulvQecHs1e4zFVVAqm8mqex-umdlPbPUGT8xzYN-G0oLMdj3uMAAeSuyrdAifVXWSXyyyBHU5rIp-8anGWj_9RQrwvOH7MOIerV3Lej1-lEOxTw\",\"der\":null,\"jwk\":null}" }';

$body = json_decode($body, true);
$body = json_decode($body['data'], true);
$keyId = $body['keyId'];

由于您在其中标记了 PHP,这是我的服务器端答案。

编辑:

您必须将 $body 变量设为字符串。在它周围加上引号。经过测试和确认,这是可行的。

【讨论】:

  • 嗯,JWK 响应对于每个事务都是唯一的,所以我不能像这样对 $body 进行硬编码。我试过这个,但得到一个未定义索引的错误:数据
猜你喜欢
  • 2019-05-24
  • 2013-05-30
  • 2018-06-26
  • 1970-01-01
  • 2012-08-03
  • 2018-11-27
  • 2019-09-22
  • 1970-01-01
  • 2019-08-16
相关资源
最近更新 更多