

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

# 使用 Secrets Manager API 和 适用于 PHP 的 Amazon SDK 版本 3 来管理密钥
<a name="secretsmanager-examples-manage-secret"></a>

Amazon Secrets Manager 存储和管理共享密钥，如密码、API 密钥和数据库凭证。借助 Secrets Manager 服务，开发人员可以将已部署代码中的硬编码的凭证替换为对 Secrets Manager 的嵌入式调用。

Secrets Manager 原生支持对 Amazon Relational Database Service (Amazon RDS) 数据库的自动计划凭证轮换，从而增强应用程序安全性。Secrets Manager 还可以使用 Amazon Lambda 来无缝轮换其他数据库和第三方服务的密钥，以实现特定于服务的详细信息。

以下示例演示如何：
+ 使用 [CreateSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#createsecret) 创建密钥。
+ 使用 [GetSecretValue](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#getsecretvalue) 检索密钥。
+ 使用 [ListSecrets](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#listsecrets) 列出 Secrets Manager 存储的所有密钥。
+ 使用 [DescribeSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#describesecret) 获取有关指定密钥的详细信息。
+ 使用 [PutSecretValue](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#putsecretvalue) 更新指定密钥。
+ 使用 [RotateSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#rotatesecret) 设置密钥轮换。
+ 使用 [DeleteSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#deletesecret) 标记密钥以进行删除。

适用于 PHP 的 Amazon SDKGitHub[ 上提供了](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code)的所有示例代码。

## 凭证
<a name="examplecredentials"></a>

运行示例代码之前，请配置您的 Amazon 凭证，如 [Amazon 使用 适用于 PHP 的 Amazon SDK 版本 3 进行身份验证](credentials.md) 中所述。然后导入 适用于 PHP 的 Amazon SDK，如 [安装 适用于 PHP 的 Amazon SDK 版本 3](getting-started_installation.md) 中所述。

## 在 Secrets Manager 中创建密钥
<a name="create-a-secret-in-asm"></a>

要在 Secrets Manager 中创建密钥，请使用 [CreateSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#createsecret) 操作。

在此示例中，用户名和密码将存储为 JSON 字符串。

 **导入**。

```
require 'vendor/autoload.php';
use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);
$secretName = 'MySecretName';
$secret = json_encode([
    "username" => getenv("SMDEMO_USERNAME"),
    "password" => getenv("SMDEMO_PASSWORD"),
]);
$description = '<<Description>>';
try {
    $result = $client->createSecret([
        'Description' => $description,
        'Name' => $secretName,
        'SecretString' => $secret,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 从 Secrets Manager 中检索密钥
<a name="retrieve-a-secret-from-asm"></a>

要检索存储在 Secrets Manager 中的密钥值，请使用 [GetSecretValue](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#getsecretvalue) 操作。

在此示例中，`secret` 是一个包含存储值的字符串。如果 `username` 的值为 `<<USERNAME>>`，并且 `password` 的值为 `<<PASSWORD>>`，则 `secret` 的输出为：

```
{"username":"<<USERNAME>>","password":"<<PASSWORD>>"}
```

用 `json_decode($secret, true)` 来访问数组值。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-east-1',
]);

$secretName = 'MySecretName';

try {
    $result = $client->getSecretValue([
        'SecretId' => $secretName,
    ]);
} catch (AwsException $e) {
    $error = $e->getAwsErrorCode();
    if ($error == 'DecryptionFailureException') {
        // Secrets Manager can't decrypt the protected secret text using the provided AWS KMS key.
        // Handle the exception here, and/or rethrow as needed.
        throw $e;
    }
    if ($error == 'InternalServiceErrorException') {
        // An error occurred on the server side.
        // Handle the exception here, and/or rethrow as needed.
        throw $e;
    }
    if ($error == 'InvalidParameterException') {
        // You provided an invalid value for a parameter.
        // Handle the exception here, and/or rethrow as needed.
        throw $e;
    }
    if ($error == 'InvalidRequestException') {
        // You provided a parameter value that is not valid for the current state of the resource.
        // Handle the exception here, and/or rethrow as needed.
        throw $e;
    }
    if ($error == 'ResourceNotFoundException') {
        // We can't find the resource that you asked for.
        // Handle the exception here, and/or rethrow as needed.
        throw $e;
    }
}
// Decrypts secret using the associated KMS CMK.
// Depending on whether the secret is a string or binary, one of these fields will be populated.
if (isset($result['SecretString'])) {
    $secret = $result['SecretString'];
} else {
    $secret = base64_decode($result['SecretBinary']);
}
print $secret;
$secretArray = json_decode($secret, true);
$username = $secretArray['username'];
$password = $secretArray['password'];

// Your code goes here;
```

## 列出 Secrets Manager 中存储的密钥
<a name="list-secrets-stored-in-asm"></a>

使用 [ListSecrets](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#listsecrets) 操作获取由 Secrets Manager 存储的所有密钥的列表。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);

try {
    $result = $client->listSecrets([
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 检索有关密钥的详细信息
<a name="retrieve-details-about-a-secret"></a>

存储的密钥包含有关轮换规则、上次访问或更改密钥、用户创建的标签和 Amazon 资源名称 (ARN) 的元数据。要获取存储在 Secrets Manager 中的指定密钥的详细信息，请使用 [DescribeSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#describesecret) 操作。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);

$secretName = 'MySecretName';

try {
    $result = $client->describeSecret([
        'SecretId' => $secretName,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 更新密钥值
<a name="update-the-secret-value"></a>

要将新加密的密钥值存储在 Secrets Manager 中，请使用 [PutSecretValue](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#putsecretvalue) 操作。

这将创建密钥的一个新版本。如果密钥的某个版本已存在，则在 `VersionStages` 中添加带该值的 `AWSCURRENT` 参数，以确保在检索该值时使用新值。

 **导入**。

```
require 'vendor/autoload.php';
use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);
$secretName = 'MySecretName';
$secret = json_encode([
    "username" => getenv("SMDEMO_USERNAME"),
    "password" => getenv("SMDEMO_PASSWORD"),
]);
try {
    $result = $client->putSecretValue([
        'SecretId' => $secretName,
        'SecretString' => $secret,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 将值轮换到 Secrets Manager 中的现有密钥
<a name="rotate-the-value-to-an-existing-secret-in-asm"></a>

要轮换存储在 Secrets Manager 中的现有密钥的值，请使用 Lambda 轮换函数和 [RotateSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#rotatesecret) 操作。

在开始之前，请创建一个 Lambda 函数来轮换您的密钥。[Amazon 代码示例目录](https://docs.amazonaws.cn/code-samples/latest/catalog/code-catalog-lambda_functions-secretsmanager.html)目前包含用于轮换 Amazon RDS 数据库凭证的多个 Lambda 代码示例。

**注意**  
有关轮换密钥的更多信息，请参阅 Amazon Secrets Manager 用户指南中的[轮换 Amazon Secrets Manager 密钥](https://docs.amazonaws.cn/secretsmanager/latest/userguide/rotating-secrets.html)。

设置您的 Lambda 函数后，配置一个新的密钥轮换。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);

$secretName = 'MySecretName';
$lambda_ARN = 'arn:aws:lambda:us-west-2:123456789012:function:MyTestDatabaseRotationLambda';
$rules = ['AutomaticallyAfterDays' => 30];

try {
    $result = $client->rotateSecret([
        'RotationLambdaARN' => $lambda_ARN,
        'RotationRules' => $rules,
        'SecretId' => $secretName,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

配置轮换时，您可以使用 [RotateSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#rotatesecret) 操作实施轮换。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);

$secretName = 'MySecretName';

try {
    $result = $client->rotateSecret([
        'SecretId' => $secretName,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 从 Secrets Manager 中删除密钥
<a name="delete-a-secret-from-asm"></a>

要从 Secrets Manager 中删除指定密钥，请使用 [DeleteSecret](https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-secretsmanager-2017-10-17.html#deletesecret) 操作。要防止意外删除密钥，将自动为密钥添加 DeletionDate 戳，用于指定您可恢复删除的恢复时间范围。如果未指定恢复时间窗口的范围，则默认时间范围为 30 天。

 **导入**。

```
require 'vendor/autoload.php';

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
```

 **示例代码** 

```
$client = new SecretsManagerClient([
    'profile' => 'default',
    'version' => '2017-10-17',
    'region' => 'us-west-2'
]);

$secretName = 'MySecretName';

try {
    $result = $client->deleteSecret([
        'SecretId' => $secretName,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo "\n";
}
```

## 相关信息
<a name="related-information"></a>

适用于 PHP 的 Amazon SDK 示例使用 Amazon Secrets Manager API 参考中的以下 REST 操作：
+  [CreateSecret](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_CreateSecret.html) 
+  [GetSecretValue](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_GetSecretValue.html) 
+  [ListSecrets](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_ListSecrets.html) 
+  [DescribeSecret](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_DescribeSecret.html) 
+  [PutSecretValue](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_PutSecretValue.html) 
+  [： RotateSecret](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_RotateSecret.html) 
+  [DeleteSecret](https://docs.amazonaws.cn/secretsmanager/latest/apireference/API_DeleteSecret.html) 

有关使用 Amazon Secrets Manager 的更多信息，请参阅 [Amazon Secrets Manager 用户指南](https://docs.amazonaws.cn/secretsmanager/latest/userguide/)。