使用服务器到服务器 API 打开 SSL 和 PHP

Open SSL and PHP with Server to Server API

我正在使用以下简单示例,使用开放式 SSL 来加密和解密消息中的签名和数据。我正在尝试了解 public 以及私钥和签名如何处理两个网站之间的数据通信。

我想做的是通过 curl 将数据发送到另一个网站上的 api,并且在 API 中能够验证签名并解压数据,如果 openssl_verify是真的。

我在 API 部分的最后一条命令中收到一个错误,指示未定义 $data。

我有三个问题:

  1. 我该如何解决这个错误?
  2. 在 API 部分,我对确认签名和解压缩数据的最佳做法有点困惑。有比我想做的更好的方法吗?
  3. 是否可以使用 oauth2 更轻松地完成 API 验证过程(API 时没有用户输入)?

以下代码适用于网站 1,在用户提交 Web 表单后,它从表单中捕获名称并使用 open ssl 加密名称并创建签名。

<?php
        
        //Private key here for testing only, realize this has be be in highly secure location.
        $private_key = <<<EOD
        -----BEGIN RSA PRIVATE KEY----- 
        MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z
        RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9
        sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R
        6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ
        h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n
        Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra
        I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI
        -----END RSA PRIVATE KEY-----
        EOD;
        
        $public_key = <<<EOD
        -----BEGIN PUBLIC KEY-----
        MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6
        zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==
        -----END PUBLIC KEY-----
        EOD;
        
        if (isset($_POST['name']) && $_POST['name']!="") {
        
            $binary_signature = "";
            $data = $_POST['name'];
            echo $data;
        
            openssl_public_encrypt($data, $encrypted, $public_key, OPENSSL_PKCS1_PADDING);
        
            $data = base64_encode($encrypted);
        
            openssl_sign($data, $binary_signature, $private_key, OPENSSL_ALGO_SHA256);
        
            $binary_signature=base64_url_encode($binary_signature);
            $url = "http://localhost/api/api.php?binary_signature=".$binary_signature;
            
            $client = curl_init($url);
            curl_setopt($client,CURLOPT_RETURNTRANSFER,true);
            $response = curl_exec($client);
            $result = json_decode($response);
        
            echo "<table>";
            echo "<tr><td>Name:</td><td>$result->data</td></tr>";
            echo "<tr><td>Amount:</td><td>$result->amount</td></tr>";
            echo "<tr><td>Response Code:</td><td>$result->response_code</td></tr>";
            echo "<tr><td>Response Desc:</td><td>$result->response_desc</td></tr>";
            echo "</table>";
        
        }
        
        function base64_url_encode($input) {
            return strtr(base64_encode($input), '+/=', '-_,');
        }
        
?>

这是 api 所在的网站 2。目标是验证签名并解压缩消息。我在 $ok = 处收到错误,因为它找不到 $data.

     <?php
    
     //Private key here for testing only, realize this has be be in highly secure location.
    $private_key = <<<EOD
    -----BEGIN RSA PRIVATE KEY----- 
    MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z
    RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9
    sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R
    6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ
    h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n
    Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra
    I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI
    -----END RSA PRIVATE KEY-----
    EOD;
    
    $public_key = <<<EOD
    -----BEGIN PUBLIC KEY-----
    MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6
    zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==
    -----END PUBLIC KEY-----
    EOD;

   if (isset($_GET['binary_signature']) && $_GET['binary_signature']!="") {
        
        $signature=$_GET['binary_signature'];
                
        $signature=base64_decode($signature);
        
        
        // Check signature
        $ok = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);

     // more code would go here to test if verify is ok and then unpack the message.

    ?>

您也可以将 url 中的 $data 变量从第一个文件传递到 api.php 文件 - 将 $url 更改为:

$url = "http://localhost/api/api.php?binary_signature=".$binary_signature."&data=".$data;

在第一个文件中执行此操作,您将能够执行以下操作: $data = $_GET['data']; 在 api.php 文件中将其放在 $signature=base64_decode($signature); 之后和 :

之前
// Check signature
    $ok = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);

即- (api.php) - 显示相关区域:

if (isset($_GET['binary_signature']) && $_GET['binary_signature']!="") {
    
    $signature=$_GET['binary_signature'];
            
    $signature=base64_decode($signature);
    
    $data = $_GET['data'];
    
    // Check signature
    $ok = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA256);

 // more code would go here to test if verify is ok and then unpack the message.

?>