本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 Amazon S3 客户端加密Amazon SDK for PHP第 3 版
使用客户端加密,数据可在您的环境中直接加密和解密。这意味着这些数据在传输到 Amazon S3 之前会经过加密,而且您无需依赖外部服务来为您处理加密。对于新的实现,我们建议使用S3EncryptionClientV2
和S3EncryptionMultipartUploaderV2
超过已弃用的S3EncryptionClient
和S3EncryptionMultipartUploader
。建议仍在使用已弃用版本的较旧实现尝试迁移。S3EncryptionClientV2
继续支持解密使用旧版加密的数据S3EncryptionClient
。
Amazon SDK for PHP实施信封加密,并使用 OpenSSL
迁移指南
对于那些试图从已弃用的客户端迁移到新客户端的用户,可以找到一份迁移指南这里。
设置
要开始使用客户端加密,您需要:
-
一个 S3 存储桶
在运行任何示例代码之前,请配置您的Amazon证书。见的证书Amazon SDK for PHP第 3 版。
加密
将加密对象上传到S3EncryptionClientV2
在标准的基础上额外使用三个参数PutObject
参数:
-
'@KmsEncryptionContext'
是一个键值对,可用于为您的加密对象添加额外的安全层。加密客户端必须传入相同的密钥,它将在 get 调用时自动传入该密钥。如果不需要其他上下文,请传入一个空数组。 -
@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'), ]);
注意
除了亚马逊 S3 和Amazon KMS基于服务的错误,你可能会收到抛出的InvalidArgumentException
对象,如果是你的'@CipherOptions'
配置不正确。
解密
下载和解密对象除了标准参数外,还有四个额外的参数,其中两个是必需的GetObject
参数。客户端将为您检测基本的密码选项。
-
-
'@SecurityProfile'
: 如果设置为 “V2”,则仅在兼容 V2 的情况下加密的对象 -
格式可以解密。将此参数设置为 “V2_AND_LEGACY” 还允许解密以 V1 兼容格式加密的对象。要支持迁移,请设置 @SecurityProfile改为 “V2_AND_LEGACY”。仅在开发新应用程序时使用 “V2”。
-
-
-
'@MaterialsProvider'
是一个处理生成密码密钥和初始化向量的提供者,如 -
以及加密你的密码密钥。
-
-
-
'@KmsAllowDecryptWithAnyCmk'
:(可选)将此参数设置为 true 可启用解密 -
而不向的构造函数提供 KMS 密钥 IDMaterialsProvider。默认值为 false。
-
-
-
'@CipherOptions'
(可选)是加密的其他配置,包括哪些 -
要使用的密码和密钥大小。
-
$result = $encryptionClient->getObject([ '@KmsAllowDecryptWithAnyCmk' => true, '@SecurityProfile' => 'V2_AND_LEGACY', '@MaterialsProvider' => $materialsProvider, '@CipherOptions' => $cipherOptions, 'Bucket' => $bucket, 'Key' => $key, ]);
注意
除了亚马逊 S3 和Amazon KMS基于服务的错误,你可能会收到抛出的InvalidArgumentException
对象,如果是你的'@CipherOptions'
配置不正确。
密码配置
-
'Cipher'
(字符串) -
加密客户端在加密时使用的密码方法。目前仅支持 “gcm”。
重要
PHP 通过版本 7.1 的更新S3EncryptionClientV2
和S3EncryptionMultipartUploaderV2
。但是,使用 polyfill 处理大型输入的性能会比使用 PHP 7.1+ 的本机实现慢得多,因此可能需要升级较旧的 PHP 版本环境才能有效地使用它们。
-
'KeySize'
(int) -
生成的用于加密的内容加密密钥的长度。默认为 256 位。有效的配置选项为 256 位和 128 位。
-
'Aad'
(字符串) -
可添加到加密负载中的可选“附加身份验证数据”。在解密时将验证此信息。
Aad
仅在使用“gcm”密码时才可用。
重要
并非所有人都支持其他身份验证数据AmazonSDK 以及其他软件开发工具包可能无法解密使用此参数加密的文件。
元数据策略
您还可以选择提供实施 Aws\Crypto\MetadataStrategyInterface
的类的实例。这个简单的接口可保存和加载 Aws\Crypto\MetadataEnvelope
,其中包含您的信封加密材料。开发工具包提供两个类来实施此功能:Aws\S3\Crypto\HeadersMetadataStrategy
和 Aws\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\MultipartUploader
和 Aws\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();
注意
除了亚马逊 S3 和Amazon KMS基于服务的错误,你可能会收到抛出的InvalidArgumentException
对象,如果是你的'@CipherOptions'
配置不正确。