mastercard / client-encryption
符合Mastercard API负载加密/解密的库。
Requires
- galbar/jsonpath: ^2.0
- phpseclib/phpseclib: ~3.0
- symfony/polyfill-php70: ^1.19
Requires (Dev)
- guzzlehttp/guzzle: ^6.2
- phake/phake: *
- yoast/phpunit-polyfills: ^1.0
Suggests
- psr/http-message: Allow usage of the PsrHttpMessageEncryptionInterceptor class
README
目录
概述
符合Mastercard API负载加密/解密的库。
兼容性
PHP 7.0+
参考
版本管理和弃用策略
使用方法
先决条件
在开始使用此库之前,您需要在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
类中的encryptPayload
和decryptPayload
方法。
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 头部进行加密
加密可以按照以下步骤执行
- 通过调用
FieldLevelEncryptionParams::generate
生成参数
$params = FieldLevelEncryptionParams::generate($config);
- 更新请求头
$request->setHeader($config->getIvHeaderName(), $params->getIvValue()); $request->setHeader($config->getEncryptedKeyHeaderName(), $params->getEncryptedKeyValue()); // …
- 使用参数调用
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 头部进行解密
解密可以按照以下步骤执行
- 读取响应头
$ivValue = $response->getHeader($config->getIvHeaderName()); $encryptedKeyValue = $response->getHeader($config->getEncryptedKeyHeaderName()); // …
- 创建一个
FieldLevelEncryptionParams
实例
$params = new FieldLevelEncryptionParams($config, $ivValue, $encryptedKeyValue, …, );
- 使用参数调用
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
类中的 encryptPayload
和 decryptPayload
。
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
另请参阅
- JweConfig.php 以查看所有配置选项
- 客户端加密 PHP 的服务配置
执行加密
使用 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 Generator 从 OpenAPI 规范 生成 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); // …