paragonie / ciphersweet-provider-aws-kms
由 AWS KMS 支持的 CipherSweet 密钥提供程序
Requires
- php: ^8.1
- aws/aws-sdk-php: ^3
- paragonie/certainty: ^2.9
- paragonie/ciphersweet: ^4.7
- psr/simple-cache: ^3
Requires (Dev)
- ext-pdo_sqlite: *
- paragonie/easydb: ^3
- phpunit/phpunit: ^9
- vimeo/psalm: ^4
README
此仓库旨在提供一个独特的 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);