Amazon S3客户端加密配合AWS SDK for PHP版本 3 中的 - 适用于 PHP 的 AWS 开发工具包
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon S3客户端加密配合AWS SDK for PHP版本 3 中的

使用客户端加密,数据可在您的环境中直接加密和解密。这就意味着,数据在传输到 Amazon S3 之前已加密,您无需使用外部服务来处理加密。对于新的实现,我们建议使用S3EncryptionClientV2S3EncryptionMultipartUploaderV2超过已弃用S3EncryptionClientS3EncryptionMultipartUploader。建议仍在使用过时版本的旧实现尝试迁移。S3EncryptionClientV2维护对使用旧版本加密的数据进行解密的支持S3EncryptionClient

AWS SDK for PHP实施信封加密,并使用 OpenSSL 进行加密和解密。此实施可与匹配其功能支持的其他开发工具包实现互操作。它还与开发工具包基于 Promise 的异步工作流程相兼容。

迁移指南

对于那些试图从弃用的客户端迁移到新客户端的用户,有一个迁移指南,可以在此处

Setup

要开始使用客户端加密,您需要:

运行任何示例代码之前,请配置您的 AWS 凭证。请参阅适用于 PHP 的 AWS 开发工具包版本 3 的凭证

Encryption

将加密对象上传到S3EncryptionClientV2需要三个附加参数,在标准PutObject参数:参数:

  • '@KmsEncryptionContext'是一个键值对,可用于为加密对象添加额外的安全层。加密客户端必须传入相同的密钥,它将在获取呼叫时自动执行此操作。如果不需要额外的上下文,则传入一个空数组。

  • @CipherOptions是加密的附加配置,包括要使用的密码和密钥大小。

  • @MaterialsProvider是一个处理生成密码密钥和初始化向量以及加密密钥的提供程序。

use Aws\S3\S3Client; use Aws\S3\Crypto\S3EncryptionClientV2; use Aws\Kms\KmsClient; use Aws\Crypto\KmsMaterialsProviderV2; // Let's construct our S3EncryptionClient using an S3Client $encryptionClient = new S3EncryptionClientV2( new S3Client([ 'profile' => 'default', 'region' => 'us-east-1', 'version' => 'latest', ]) ); $kmsKeyId = 'kms-key-id'; $materialsProvider = new KmsMaterialsProviderV2( new KmsClient([ 'profile' => 'default', 'region' => 'us-east-1', 'version' => 'latest', ]), $kmsKeyId ); $bucket = 'the-bucket-name'; $key = 'the-file-name'; $cipherOptions = [ 'Cipher' => 'gcm', 'KeySize' => 256, // Additional configuration options ]; $result = $encryptionClient->putObject([ '@MaterialsProvider' => $materialsProvider, '@CipherOptions' => $cipherOptions, '@KmsEncryptionContext' => ['context-key' => 'context-value'], 'Bucket' => $bucket, 'Key' => $key, 'Body' => fopen('file-to-encrypt.txt', 'r'), ]);
注意

如果 '@CipherOptions' 配置不正确,除了基于 Amazon S3 和 AWS KMS 的服务错误,您可能还会收到引发的 InvalidArgumentException 对象。

Decryption

下载和解密对象有四个附加参数,其中两个是必需的,位于标准GetObject参数。客户端将为您检测基本的密码选项。

  • '@SecurityProfile':如果设置为 “V2”,则仅在 V2 兼容中加密的对象

    格式可以解密。将此参数设置为 “V2_AND_LEGATE” 还允许对以 V1 兼容格式加密的对象进行解密。要支持迁移,请将 @SecurityProfile 设置为 “V2_AND_LEGCACY”。仅在新应用程序开发中使用 “V2”。

  • '@MaterialsProvider'是一个处理生成密码键和初始化向量的提供程序,因为

    以及加密您的密码密钥。

  • '@KmsAllowDecryptWithAnyCmk':(可选)将此参数设置为 true 启用解密

    而不向材料提供程序的构造函数提供 KMS 密钥 ID。默认值为 False。

  • '@CipherOptions'(可选)是加密的附加配置,包括

    要使用的密码和密钥大小。

$result = $encryptionClient->getObject([ '@KmsAllowDecryptWithAnyCmk' => true, '@SecurityProfile' => 'V2_AND_LEGACY', '@MaterialsProvider' => $materialsProvider, '@CipherOptions' => $cipherOptions, 'Bucket' => $bucket, 'Key' => $key, ]);
注意

如果 '@CipherOptions' 配置不正确,除了基于 Amazon S3 和 AWS KMS 的服务错误,您可能还会收到引发的 InvalidArgumentException 对象。

密码配置

'Cipher'(字符串)

加密客户端在加密时使用的密码方法。目前只支持 “gcm”。

重要

PHP 通过版本 7.1 的更新包含了额外的参数,在使用 OpenSSL 进行 GCM 加密时,这些参数对于加密解密是必要的。对于 PHP 版本 7.0 和更早版本,加密客户端提供并使用 GCM 支持的 polyfillS3EncryptionClientV2S3EncryptionMultipartUploaderV2。但是,使用 polyfill 的大型输入的性能要比使用 PHP 7.1+ 的本机实现要慢得多,因此升级旧版本的 PHP 环境可能需要有效地使用它们。

'KeySize' (int)

生成的用于加密的内容加密密钥的长度。默认为 256 位。有效的配置选项为 256 位和 128 位。

'Aad'(字符串)

可添加到加密负载中的可选“附加身份验证数据”。在解密时将验证此信息。Aad使用 'gcm' 密码时才可用。

重要

并非所有 AWS 开发工具包都支持其他身份验证数据,因此其他开发工具包可能无法解密使用此参数加密的文件。

元数据策略

您还可以选择提供实施 Aws\Crypto\MetadataStrategyInterface 的类的实例。这个简单的接口可保存和加载 Aws\Crypto\MetadataEnvelope,其中包含您的信封加密材料。开发工具包提供两个类来实施此功能:Aws\S3\Crypto\HeadersMetadataStrategyAws\S3\Crypto\InstructionFileMetadataStrategy。默认使用 HeadersMetadataStrategy

$strategy = new InstructionFileMetadataStrategy( $s3Client ); $encryptionClient->putObject([ '@MaterialsProvider' => $materialsProvider, '@MetadataStrategy' => $strategy, '@KmsEncryptionContext' => [], '@CipherOptions' => $cipherOptions, 'Bucket' => $bucket, 'Key' => $key, 'Body' => fopen('file-to-encrypt.txt', 'r'), ]); $result = $encryptionClient->getObject([ '@KmsAllowDecryptWithAnyCmk' => false, '@MaterialsProvider' => $materialsProvider, '@SecurityProfile' => 'V2', '@MetadataStrategy' => $strategy, '@CipherOptions' => $cipherOptions, 'Bucket' => $bucket, 'Key' => $key, ]);

调用 HeadersMetadataStrategy::classInstructionFileMetadataStrategy 也可提供 的类名常量。

$result = $encryptionClient->putObject([ '@MaterialsProvider' => $materialsProvider, '@MetadataStrategy' => HeadersMetadataStrategy::class, '@CipherOptions' => $cipherOptions, 'Bucket' => $bucket, 'Key' => $key, 'Body' => fopen('file-to-encrypt.txt', 'r'), ]);
注意

如果构造文件上传后发生错误,不会自动删除该文件。

分段上传

也可以利用客户端加密执行分段上传。这些区域有:Aws\S3\Crypto\S3EncryptionMultipartUploaderV2会在上传之前准备用于加密的源流。使用 Aws\S3\MultipartUploaderAws\S3\Crypto\S3EncryptionClientV2 创建的过程也与此类似。S3EncryptionMultipartUploaderV2 能以与 '@MetadataStrategy' 相同的方式处理 S3EncryptionClientV2 选项,以及所有可用的 '@CipherOptions' 配置。

$kmsKeyId = 'kms-key-id'; $materialsProvider = new KmsMaterialsProviderV2( new KmsClient([ 'region' => 'us-east-1', 'version' => 'latest', 'profile' => 'default', ]), $kmsKeyId ); $bucket = 'the-bucket-name'; $key = 'the-upload-key'; $cipherOptions = [ 'Cipher' => 'gcm' 'KeySize' => 256, // Additional configuration options ]; $multipartUploader = new S3EncryptionMultipartUploaderV2( new S3Client([ 'region' => 'us-east-1', 'version' => 'latest', 'profile' => 'default', ]), fopen('large-file-to-encrypt.txt', 'r'), [ '@MaterialsProvider' => $materialsProvider, '@CipherOptions' => $cipherOptions, 'bucket' => $bucket, 'key' => $key, ] ); $multipartUploader->upload();
注意

如果 '@CipherOptions' 配置不正确,除了基于 Amazon S3 和 AWS KMS 的服务错误,您可能还会收到引发的 InvalidArgumentException 对象。