paragonie/ciphersweet-provider-aws-kms

由 AWS KMS 支持的 CipherSweet 密钥提供程序

v0.1.0 2024-05-13 23:34 UTC

This package is auto-updated.

Last update: 2024-09-14 00:32:16 UTC


README

Static Analysis Latest Stable Version Latest Unstable Version License Downloads

此仓库旨在提供一个独特的 Composer 包,用于集成 CipherSweet 与 AWS KMS。

安装

composer require paragonie/ciphersweet-provider-aws-kms

使用

KmsKeyProvider

基本的 KmsKeyProvider 类旨在与单个加密数据密钥 (EDK) 一起工作。如果您正在寻找多租户支持(例如,每个用户一个数据密钥),请查看 MultiTenantKmsKeyProvider

首先,您需要一个 KmsClient 对象、所需的 CipherSweet 后端 以及您想要使用的 KMS 密钥的 Key ID 或 ARN。

<?php
use Aws\Kms\KmsClient;
use ParagonIE\Certainty\RemoteFetch;
use ParagonIE\CipherSweet\Backend\BoringCrypto;
use ParagonIE\CipherSweet\KeyProvider\KmsKeyProvider;

// Recommended: always use the latest CACert bundle
$remoteFetch = new RemoteFetch('/path/to/cacert-dir');
$latestBundle = $remoteFetch->getLatestBundle()->getFilePath();
$keyID = ''; /* get this from KMS */

$kmsClient = new KmsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'http' => ['verify' => $latestBundle]
]);

// Recommended: Use encryption context for your apps
$encryptionContext = [
    'app' => 'foo.example.com'
];

一旦定义了这些值,您将首先想要生成一个新的数据密钥,并持久化加密数据密钥以供重用,如下所示

$newKey = KmsKeyProvider::generate(
    $kmsClient,
    new BoringCrypto(), // Your backend goes here
    $keyID,
    $encryptionContext
);
// Save this somewhere so you can reuse it:
$edk = $newKey->getEncryptedDataKey();

从现在开始,您可以简单地按如下方式加载您的后端

// Moving forward, you can simply instantiate your key provider like so:
$provider = new KmsKeyProvider(
    $kmsClient,
    new BoringCrypto(), // Your backend goes here
    $keyID,
    $encryptionContext,
    $edk
);

另请参阅: 缓存

MultiTenantKmsKeyProvider

提供的 MultiTenantKmsKeyProvider 类的目的是为了简化多个用户使用不同的 EDK 加密数据的工作负载。它可以安全地与同一 KMS 密钥或不同的 KMS 密钥一起使用。这取决于您的应用程序。

我们设计的背后基本思想是,租户的一些元数据存储在一个列中(该列为每一行提供了一个填充值)

/** @var \ParagonIE\CipherSweet\KeyProvider\MultiTenantKmsKeyProvider $multiPro */
$multiPro->setTenantColumnForTable('table_name', 'tenant_id_column_name');

在您的应用程序的其他地方,您需要将租户 ID 与 EDK 进行映射。这 可能 是一个单独的 SQL 表。我们已经提供了一些方便的实用工具来简化集成,但您也可以自行决定映射和持久化策略。

为此,我们的多租户密钥提供程序允许您提供一个实现了 TenantEDKInterface 的类来获取 EDK 和其他元数据,以及创建租户。您可以随意实现这一点。 例如,请参阅我们的 EasyDB 测试类

要创建一个新的租户(以及一个新的 EDK),只需传递新租户的 ID、KMS 密钥 ID 或 ARN 以及用于加密此密钥的加密上下文。

// Calling createTenant() will persist it to memory
$specificProvider = $multiPro->createTenant($tenantID, $kmsKeyID, $encryptionContext);

通过在您的端点上添加一点额外的粘合代码,您就准备好了。

<?php
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\EncryptedMultiRows;
use ParagonIE\CipherSweet\KeyProvider\MultiTenantKmsKeyProvider;

/**
 * @var \Aws\Kms\KmsClient $kmsClient
 * @var \ParagonIE\CipherSweet\KeyProvider\TenantEDKInterface $edkLookup
 */

$multiPro = (new MultiTenantKmsKeyProvider())
    ->setEDKLookup($edkLookup)
    ->setKmsClient($kmsClient);

$multiPro->setTenantColumnForTable('table_1_name', 'tenant_id');

$multiPro->createTenant('example_1', 'kms_key_id_goes_here', ['region' => 'us-east-2']);
$multiPro->createTenant('example_2', 'kms_key_id_goes_here', ['region' => 'us-west-1']);

$engine = new CipherSweet($multiPro, $multiPro->getBackend());
$encryptManyRows = (new EncryptedMultiRows($engine))->setAutoBindContext(true);

然后您就可以像往常一样 使用 CipherSweet

缓存

与 AWS KMS 的网络往返可能会成为您应用程序的性能瓶颈,尤其是如果您在 AWS 外运行应用程序。

应用程序 可能 提供一个 PSR-16 兼容的缓存来持久化请求之间的明文数据密钥。

/**
 * @var \ParagonIE\CipherSweet\KeyProvider\MultiTenantKmsKeyProvider $multiPro
 * @var \ParagonIE\CipherSweet\KeyProvider\KmsKeyProvider $provider
 * @var \Psr\SimpleCache\CacheInterface $yourCache
 */

// This will pass $yourCache to all KmsKeyProviders managed by this multi-tenant provider:
$multiPro->setDataKeyCache($yourCache);

// For only one single-tenant provider:
$provider->setDataKeyCache($yourCache);