本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用 AWS SDK for PHP 版本 3 的 Amazon S3 客户端加密
使用客户端加密,数据可在您的环境中直接加密和解密。这就意味着,数据在传输到 Amazon S3 之前已加密,您无需使用外部服务来处理加密。对于新的实现,我们建议使用 S3EncryptionClientV2
和 S3EncryptionMultipartUploaderV2
来替代已弃用的 S3EncryptionClient
和 S3EncryptionMultipartUploader
。建议仍在使用已弃用版本的旧实现尝试迁移。S3EncryptionClientV2
继续支持对使用旧版 S3EncryptionClient
加密的数据进行解密。
AWS SDK for PHP实施信封加密,并使用 OpenSSL
迁移指南
对于尝试从已弃用客户端迁移到新客户端的用户,可以在此处找到迁移指南。
设置
要开始使用客户端加密,您需要:
运行任何示例代码之前,请配置您的 AWS 凭证。请参阅 AWS 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'),
]);
注意
如果 '@CipherOptions'
配置不正确,除了基于 Amazon S3 和 AWS KMS 的服务错误,您可能还会收到抛出的 InvalidArgumentException
对象。
解密
下载和解密对象时,除了标准 GetObject
参数外,还有四个额外参数,其中两个是必需的。客户端将为您检测基本的密码选项。
-
-
'@SecurityProfile'
:如果设置为“V2”,则仅解密以 V2 兼容格式加密 -
的对象。将此参数设置为“V2_AND_LEGACY”,也允许解密以 V1 兼容格式加密的对象。要支持迁移,请将 @SecurityProfile 设置为“V2_AND_LEGACY”。“V2”仅适用于新应用程序开发。
-
-
-
'@MaterialsProvider'
是一个提供程序,用于处理生成密码密钥和初始化向量, -
以及加密密码密钥。
-
-
-
'@KmsAllowDecryptWithAnyCmk'
:(可选)将此参数设置为 True 即可启用解密, -
无需向 MaterialsProvider 的构造函数提供 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 的更新S3EncryptionClientV2
和 S3EncryptionMultipartUploaderV2
提供并使用支持 GCM 的填充代码。但是,使用填充代码来处理大型输入的性能会比使用 PHP 7.1+ 的本机实现时慢得多,因此可能需要升级较旧的 PHP 版本环境才能有效使用它们。
-
'KeySize'
(int) -
生成的用于加密的内容加密密钥的长度。默认为 256 位。有效配置选项为 256 和 128 位。
-
'Aad'
(字符串) -
可添加到加密负载中的可选“附加身份验证数据”。在解密时将验证此信息。
Aad
仅在使用“gcm”密码时才可用。
重要
并非所有 AWS SDK 都支持其他身份验证数据,因此其他 SDK 可能无法解密使用此参数加密的文件。
元数据策略
您还可以选择提供实施 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();
注意
如果 '@CipherOptions'
配置不正确,除了基于 Amazon S3 和 AWS KMS 的服务错误,您可能还会收到抛出的 InvalidArgumentException
对象。