mastercard/client-encryption

此包已被废弃且不再维护。未建议替代包。

符合Mastercard API负载加密/解密的库。

v1.5.0 2023-03-16 11:24 UTC

This package is auto-updated.

Last update: 2024-03-19 12:07:51 UTC


README

maintenance-status

目录

概述

符合Mastercard API负载加密/解密的库。

兼容性

PHP 7.0+

参考

Encryption of sensitive data

版本管理和弃用策略

使用方法

先决条件

在开始使用此库之前,您需要在Mastercard开发者门户中设置一个项目。

作为此配置的一部分,您将收到

  • 一个公共请求加密证书(又称客户端加密密钥
  • 一个私有响应解密密钥(又称Mastercard加密密钥

将库添加到您的项目

composer require mastercard/client-encryption

加载加密证书

可以通过调用EncryptionUtils::loadEncryptionCertificate从文件创建证书资源

use Mastercard\Developer\Utils\EncryptionUtils;
// …
$encryptionCertificate = EncryptionUtils::loadEncryptionCertificate('<insert certificate file path>');

支持的证书格式:PEM、DER。

加载解密密钥

从PKCS#12密钥存储

可以通过以下方式调用EncryptionUtils::loadDecryptionKey从PKCS#12密钥存储创建私有密钥资源

use Mastercard\Developer\Utils\EncryptionUtils;
// …
$decryptionKey = EncryptionUtils::loadDecryptionKey(
                                    '<insert PKCS#12 key file path>', 
                                    '<insert key alias>', 
                                    '<insert key password>');

从未加密的密钥文件

可以通过调用EncryptionUtils::loadDecryptionKey以下方式从未加密的密钥文件创建私有密钥资源

use Mastercard\Developer\Utils\EncryptionUtils;
// …
$decryptionKey = EncryptionUtils::loadDecryptionKey('<insert key file path>');

支持的RSA密钥格式

  • PKCS#1 PEM(以'-----BEGIN RSA PRIVATE KEY-----'开头)
  • PKCS#8 PEM(以'-----BEGIN PRIVATE KEY-----'开头)
  • 二进制DER编码的PKCS#8

执行字段级加密和解密

简介

负责负载加密和解密的核心方法是FieldLevelEncryption类中的encryptPayloaddecryptPayload方法。

  • encryptPayload使用方法
use Mastercard\Developer\Encryption;
// …
$encryptedRequestPayload = FieldLevelEncryption::encryptPayload($requestPayload, $config);
  • decryptPayload使用方法
use Mastercard\Developer\Encryption;
// …
$responsePayload = FieldLevelEncryption::decryptPayload($encryptedResponsePayload, $config);

配置字段级加密

使用 FieldLevelEncryptionConfigBuilder 创建 FieldLevelEncryptionConfig 实例。示例

use Mastercard\Developer\Encryption;
// …
$config = FieldLevelEncryptionConfigBuilder::aFieldLevelEncryptionConfig()
    ->withEncryptionCertificate($encryptionCertificate)
    ->withDecryptionKey($decryptionKey)
    ->withEncryptionPath('$.path.to.foo', '$.path.to.encryptedFoo')
    ->withDecryptionPath('$.path.to.encryptedFoo', '$.path.to.foo')
    ->withOaepPaddingDigestAlgorithm('SHA-256')
    ->withEncryptedValueFieldName('encryptedValue')
    ->withEncryptedKeyFieldName('encryptedKey')
    ->withIvFieldName('iv')
    ->withFieldValueEncoding(FieldValueEncoding::HEX)
    ->build();

另请参阅

执行加密

使用 JSON 请求有效负载和 FieldLevelEncryptionConfig 实例调用 FieldLevelEncryption::encryptPayload

使用上述配置的示例

use Mastercard\Developer\Encryption;
// …
$payload = '{
    "path": {
        "to": {
            "foo": {
                "sensitiveField1": "sensitiveValue1",
                "sensitiveField2": "sensitiveValue2"
            }
        }
    }
}';
$encryptedPayload = FieldLevelEncryption::encryptPayload($payload, $config);
echo (json_encode(json_decode($encryptedPayload), JSON_PRETTY_PRINT));

输出

{
    "path": {
        "to": {
            "encryptedFoo": {
                "iv": "7f1105fb0c684864a189fb3709ce3d28",
                "encryptedKey": "67f467d1b653d98411a0c6d3c…ffd4c09dd42f713a51bff2b48f937c8",
                "encryptedValue": "b73aabd267517fc09ed72455c2…dffb5fa04bf6e6ce9ade1ff514ed6141"
            }
        }
    }
}

执行解密

使用 JSON 响应有效负载和 FieldLevelEncryptionConfig 实例调用 FieldLevelEncryption::decryptPayload

使用上述配置的示例

use Mastercard\Developer\Encryption;
// …
$encryptedPayload = '{
    "path": {
        "to": {
            "encryptedFoo": {
                "iv": "e5d313c056c411170bf07ac82ede78c9",
                "encryptedKey": "e3a56746c0f9109d18b3a2652b76…f16d8afeff36b2479652f5c24ae7bd",
                "encryptedValue": "809a09d78257af5379df0c454dcdf…353ed59fe72fd4a7735c69da4080e74f"
            }
        }
    }
}';
$payload = FieldLevelEncryption::decryptPayload($encryptedPayload, $config);
echo (json_encode(json_decode($payload), JSON_PRETTY_PRINT));

输出

{
    "path": {
        "to": {
            "foo": {
                "sensitiveField1": "sensitiveValue1",
                "sensitiveField2": "sensitiveValue2"
            }
        }
    }
}

加密整个有效负载

可以使用 '$' 操作符作为加密路径来加密整个有效负载

use Mastercard\Developer\Encryption;
// …
$config = FieldLevelEncryptionConfigBuilder::aFieldLevelEncryptionConfig()
    ->withEncryptionCertificate(encryptionCertificate)
    ->withEncryptionPath('$', '$')
    // …
    ->build();

示例

use Mastercard\Developer\Encryption;
// …
$payload = '{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}';
$encryptedPayload = FieldLevelEncryption::encryptPayload($payload, $config);
echo (json_encode(json_decode($encryptedPayload), JSON_PRETTY_PRINT));

输出

{
    "iv": "1b9396c98ab2bfd195de661d70905a45",
    "encryptedKey": "7d5112fa08e554e3dbc455d0628…52e826dd10311cf0d63bbfb231a1a63ecc13",
    "encryptedValue": "e5e9340f4d2618d27f8955828c86…379b13901a3b1e2efed616b6750a90fd379515"
}

解密整个有效负载

可以使用 '$' 操作符作为解密路径来解密整个有效负载

use Mastercard\Developer\Encryption;
// …
$config = FieldLevelEncryptionConfigBuilder::aFieldLevelEncryptionConfig()
    ->withDecryptionKey(decryptionKey)
    ->withDecryptionPath('$', '$')
    // …
    ->build();

示例

use Mastercard\Developer\Encryption;
// …
$encryptedPayload = '{
    "iv": "1b9396c98ab2bfd195de661d70905a45",
    "encryptedKey": "7d5112fa08e554e3dbc455d0628…52e826dd10311cf0d63bbfb231a1a63ecc13",
    "encryptedValue": "e5e9340f4d2618d27f8955828c86…379b13901a3b1e2efed616b6750a90fd379515"
}';
$payload = FieldLevelEncryption::decryptPayload($encryptedPayload, $config);
echo (json_encode(json_decode($payload), JSON_PRETTY_PRINT));

输出

{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}

使用 HTTP 头部进行加密参数

在上面的部分中,加密参数(初始化向量、加密对称密钥等)是 HTTP 有效负载的一部分。

以下是如何配置库以使用 HTTP 头部。

使用 HTTP 头部的配置

在构建 FieldLevelEncryptionConfig 实例时,使用 with{Param}HeaderName 而不是 with{Param}FieldName。示例

use Mastercard\Developer\Encryption;
// …
$config = FieldLevelEncryptionConfigBuilder::aFieldLevelEncryptionConfig()
    ->withEncryptionCertificate(encryptionCertificate)
    ->withDecryptionKey(decryptionKey)
    ->withEncryptionPath('$', '$')
    ->withDecryptionPath('$', '$')
    ->withOaepPaddingDigestAlgorithm('SHA-256')
    ->withEncryptedValueFieldName('data')
    ->withIvHeaderName('x-iv')
    ->withEncryptedKeyHeaderName('x-encrypted-key')
    // …
    ->withFieldValueEncoding(FieldValueEncoding::HEX)
    ->build();

另请参阅

使用 HTTP 头部进行加密

加密可以按照以下步骤执行

  1. 通过调用 FieldLevelEncryptionParams::generate 生成参数
$params = FieldLevelEncryptionParams::generate($config);
  1. 更新请求头
$request->setHeader($config->getIvHeaderName(), $params->getIvValue());
$request->setHeader($config->getEncryptedKeyHeaderName(), $params->getEncryptedKeyValue());
// …
  1. 使用参数调用 encryptPayload
FieldLevelEncryption::encryptPayload($payload, $config, $params);

使用上述配置的示例

$payload = '{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}';
$encryptedPayload = FieldLevelEncryption::encryptPayload($payload, $config, $params);
echo (json_encode(json_decode($encryptedPayload), JSON_PRETTY_PRINT));

输出

{
    "data": "53b5f07ee46403af2e92abab900853…d560a0a08a1ed142099e3f4c84fe5e5"
}
使用 HTTP 头部进行解密

解密可以按照以下步骤执行

  1. 读取响应头
$ivValue = $response->getHeader($config->getIvHeaderName());
$encryptedKeyValue = $response->getHeader($config->getEncryptedKeyHeaderName());
// …
  1. 创建一个 FieldLevelEncryptionParams 实例
$params = new FieldLevelEncryptionParams($config, $ivValue, $encryptedKeyValue, …, );
  1. 使用参数调用 decryptPayload
FieldLevelEncryption::decryptPayload($encryptedPayload, $config, $params);

使用上述配置的示例

$encryptedPayload = '{
    "data": "53b5f07ee46403af2e92abab900853…d560a0a08a1ed142099e3f4c84fe5e5"
}';
$payload = FieldLevelEncryption::decryptPayload($encryptedPayload, $config, $params);
echo (json_encode(json_decode($payload), JSON_PRETTY_PRINT));

输出

{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}

执行 JWE 加密和解密

简介

负责有效负载加密和解密的核心方法是 JweEncryption 类中的 encryptPayloaddecryptPayload

  • encryptPayload使用方法
use Mastercard\Developer\Encryption;
// …
$encryptedRequestPayload = JweEncryption::encryptPayload($requestPayload, $config);
  • decryptPayload使用方法
use Mastercard\Developer\Encryption;
// …
$responsePayload = JweEncryption::decryptPayload($encryptedResponsePayload, $config);

配置 JWE 加密

使用 JweEncryptionConfigBuilder 创建 JweEncryptionConfig 实例。示例

use Mastercard\Developer\Encryption;
// …
$config = JweEncryptionConfigBuilder::aJweEncryptionConfig()
    ->withEncryptionCertificate($encryptionCertificate)
    ->withDecryptionKey($decryptionKey)
    ->withEncryptionPath('$.path.to.foo', '$.path.to.encryptedFoo')
    ->withDecryptionPath('$.path.to.encryptedFoo', '$.path.to.foo')
    ->withEncryptedValueFieldName('encryptedValue')
    ->build();

注意:如果 withEncryptedValueFieldName 留空,则默认值为 encryptedData

另请参阅

执行加密

使用 JSON 请求有效负载和 JweEncryptionConfig 实例调用 JweEncryption::encryptPayload

使用上述配置的示例

use Mastercard\Developer\Encryption;
// …
$payload = '{
    "path": {
        "to": {
            "foo": {
                "sensitiveField1": "sensitiveValue1",
                "sensitiveField2": "sensitiveValue2"
            }
        }
    }
}';
$encryptedPayload = JweEncryption::encryptPayload($payload, $config);
echo (json_encode(json_decode($encryptedPayload), JSON_PRETTY_PRINT));

输出

{
  "path": {
    "to": {
      "encryptedFoo": "809a09d78257af5379df0c454dcdf…353ed59fe72fd4a7735c69da4080e74f"
    }
  }
}

执行解密

使用 JSON 响应有效负载和 JweEncryptionConfig 实例调用 JweEncryption::decryptPayload

使用上述配置的示例

use Mastercard\Developer\Encryption;
// …
$encryptedPayload = '{
    "path": {
        "to": {
            "encryptedFoo": {
                "encryptedValue": "809a09d78257af5379df0c454dcdf…353ed59fe72fd4a7735c69da4080e74f"
            }
        }
    }
}';
$payload = JweEncryption::decryptPayload($encryptedPayload, $config);
echo (json_encode(json_decode($payload), JSON_PRETTY_PRINT));

输出

{
    "path": {
        "to": {
            "foo": {
                "sensitiveField1": "sensitiveValue1",
                "sensitiveField2": "sensitiveValue2"
            }
        }
    }
}

加密整个有效负载

可以使用 '$' 操作符作为加密路径来加密整个有效负载

use Mastercard\Developer\Encryption;
// …
$config = JweConfigBuilder::aJweEncryptionConfig()
    ->withEncryptionCertificate(encryptionCertificate)
    ->withEncryptionPath('$', '$')
    ->withEncryptedValueFieldName("encryptedValue")
    // …
    ->build();

示例

use Mastercard\Developer\Encryption;
// …
$payload = '{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}';
$encryptedPayload = JweEncryption::encryptPayload($payload, $config);
echo (json_encode(json_decode($encryptedPayload), JSON_PRETTY_PRINT));

输出

{
    "encryptedValue": "e5e9340f4d2618d27f8955828c86…379b13901a3b1e2efed616b6750a90fd379515"
}

解密整个有效负载

可以使用 '$' 操作符作为解密路径来解密整个有效负载

use Mastercard\Developer\Encryption;
// …
$config = JweEncryptionConfigBuilder::aJweEncryptionConfig()
    ->withDecryptionKey(decryptionKey)
    ->withDecryptionPath('$', '$')
    ->withEncryptedValueFieldName("encryptedValue")
    // …
    ->build();

示例

use Mastercard\Developer\Encryption;
// …
$encryptedPayload = '{
    "encryptedValue": "e5e9340f4d2618d27f8955828c86…379b13901a3b1e2efed616b6750a90fd379515"
}';
$payload = FieldLevelEncryption::decryptPayload($encryptedPayload, $config);
echo (json_encode(json_decode($payload), JSON_PRETTY_PRINT));

输出

{
    "sensitiveField1": "sensitiveValue1",
    "sensitiveField2": "sensitiveValue2"
}

与 OpenAPI Generator API 客户端库集成

OpenAPI GeneratorOpenAPI 规范 生成 API 客户端库。它提供生成器和库模板,以支持多种语言和框架。

本项目为您提供了在配置API客户端时可以使用的某些拦截器类。这些类将负责加密请求数据和解密响应数据负载,并在需要时更新HTTP头。

当前支持的生成器

php

OpenAPI生成器

可以使用以下命令生成客户端库

openapi-generator-cli generate -i openapi-spec.yaml -g php -o out

另请参阅

PsrHttpMessageEncryptionInterceptor在字段级加密中的用法
use GuzzleHttp;
use OpenAPI\Client\Api\ServiceApi;
use OpenAPI\Client\Configuration
use Mastercard\Developer\Signers\PsrHttpMessageSigner;
use Mastercard\Developer\Interceptors\PsrHttpMessageEncryptionInterceptor;
// …

$stack = new GuzzleHttp\HandlerStack();
$stack->setHandler(new GuzzleHttp\Handler\CurlHandler());
$fieldLevelEncryptionConfig = FieldLevelEncryptionConfigBuilder::aFieldLevelEncryptionConfig()
    // …
    ->build();
$fieldLevelEncryptionInterceptor = new PsrHttpMessageEncryptionInterceptor($fieldLevelEncryptionConfig);
$stack->push(GuzzleHttp\Middleware::mapRequest([$fieldLevelEncryptionInterceptor, 'interceptRequest']));
$stack->push(GuzzleHttp\Middleware::mapResponse([$fieldLevelEncryptionInterceptor, 'interceptResponse']));
$stack->push(GuzzleHttp\Middleware::mapRequest([new PsrHttpMessageSigner($consumerKey, $signingKey), 'sign']));
$options = ['handler' => $stack];
$client = new GuzzleHttp\Client($options);
$config = new Configuration();
$config->setHost('https://sandbox.api.mastercard.com');
$serviceApi = new ServiceApi($client, $config);
// …
PsrHttpMessageEncryptionInterceptor在JWE加密中的用法
use GuzzleHttp;
use OpenAPI\Client\Api\ServiceApi;
use OpenAPI\Client\Configuration
use Mastercard\Developer\Signers\PsrHttpMessageSigner;
use Mastercard\Developer\Interceptors\PsrHttpMessageEncryptionInterceptor;
// …

$stack = new GuzzleHttp\HandlerStack();
$stack->setHandler(new GuzzleHttp\Handler\CurlHandler());
$JweEncryptionConfig = JweEncryptionConfigBuilder::aJweEncryptionConfig()
    // …
    ->build();
$JweEncryptionInterceptor = new PsrHttpMessageEncryptionInterceptor($JweEncryptionConfig);
$stack->push(GuzzleHttp\Middleware::mapRequest([$JweEncryptionInterceptor, 'interceptRequest']));
$stack->push(GuzzleHttp\Middleware::mapResponse([$JweEncryptionInterceptor, 'interceptResponse']));
$stack->push(GuzzleHttp\Middleware::mapRequest([new PsrHttpMessageSigner($consumerKey, $signingKey), 'sign']));
$options = ['handler' => $stack];
$client = new GuzzleHttp\Client($options);
$config = new Configuration();
$config->setHost('https://sandbox.api.mastercard.com');
$serviceApi = new ServiceApi($client, $config);
// …