英文:
Secrets Manager Update Secret - Secret String additional JSON Encoding
问题
我正在使用AWS CLI更新一个包含x509证书的JSON密钥。我将传递给--secret-string
参数的有效负载是我期望的编码,但是当上传并存储在AWS中时,secretsmanager会对换行字符进行额外的编码。
问题
我遇到的问题是在解组密钥时,PEM和密钥内容没有完全取消转义。我有一个使用Go编写的应用程序服务器,当将密钥传递给tls.X509KeyPair()
时,它无法识别证书的内容。
我可以将CLI命令中的有效负载手动粘贴到网页上的密钥中,它会保留现有的格式,并且我的代码可以正常工作。
我主要是想看看是否有办法修复上传编码,而不是在获取密钥时在Go中格式化/取消转义PEM/密钥内容。
示例:
CLI命令:
aws secretsmanager update-secret --secret-id my-secret --secret-string '{\"PEM\":\"-----BEGIN CERTIFICATE-----\n...\n...\n...\n-----END CERTIFICATE-----\n\",\"KEY\":\"...\"}'
实际上传的密钥:
{\"PEM\":\"-----BEGIN CERTIFICATE-----\\\\n...\\\\n...\\\\n...\\\\n-----END CERTIFICATE-----\\\\n\",\"KEY\":\"...\"}
我使用awk
来连接PEM内容,使用jq
来更新+将JSON转换为字符串。转换为字符串的JSON是我要寻找的正确格式。
awk: STRING_PEM=$(awk '{printf "%s\\n", $0}' $PemFile)
jq: SECRET_STRING=$(jq -r 'tostring' $UPDATED_SECRET)
英文:
I am using the AWS CLI to update a JSON secret containing x509 certificates. The payload that I am passing into the --secret-string
parameter is the encoding I am expecting, but secretsmanager is performing additional encoding of the newline characters when it is uploaded and stored in AWS.
Problem
The problem I am getting is the PEM and Key contents are not entirely being unescaped when unmarshalling the secret. I have an application server in Go that when passing the secrets into tls.X509KeyPair()
it is unable to recognize the contents of the certificates.
I can paste the payload from the CLI command into the secret manually on the web and it retains the existing formatting and my code works fine.
I am primarily looking to see if there is something I can do to fix the upload encoding instead of having to format / unescape the PEM/Key contents in Go when fetching the secret.
Example:
CLI Command:
aws secretsmanager update-secret --secret-id my-secret --secret-string '{"PEM":"-----BEGIN CERTIFICATE-----\n...\n...\n...\n-----END CERTIFICATE-----\n","KEY":"..."}'
Actual Uploaded Secret:
{"PEM":"-----BEGIN CERTIFICATE-----\\\\n...\\\\n...\\\\n...\\\\n-----END CERTIFICATE-----\\\\n",,"KEY":"..."}
I am using awk
to join the PEM contents and jq
for updating + stringifying the JSON. The stringified JSON is the correct format I am looking for.
awk: STRING_PEM=$(awk '{printf "%s\\n", $0}' $PemFile)
jq: SECRET_STRING=$(jq -r 'tostring' $UPDATED_SECRET)
答案1
得分: 1
我可以确认,通过以下命令设置的秘密:
aws secretsmanager update-secret --secret-id my-secret --secret-string '{\"PEM\":\"-----BEGIN CERTIFICATE-----\n...\n...\n...\n-----END CERTIFICATE-----\n\",\"KEY\":\"...\"}'
按预期工作(请参考本答案底部的Go演示)。
这里是一个简化的命令,可以完成整个过程:
aws secretsmanager update-secret --secret-id -secret --secret-string "$(jq -n --arg cert "$(cat /path/to/cert/file)" --arg key "$(cat /path/to/key/file)" -c '{\"PEM\": $cert, \"KEY\": $key}')"
这是一个用于验证上传内容的Go演示:
package main
import (
"context"
"crypto/tls"
"encoding/json"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
)
func main() {
secretName := "test1"
region := "ap-southeast-1"
config, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
panic(err)
}
svc := secretsmanager.NewFromConfig(config)
input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(secretName),
}
result, err := svc.GetSecretValue(context.TODO(), input)
if err != nil {
panic(err)
}
var secret struct {
PEM string `json:"PEM"`
KEY string `json:"KEY"`
}
if err := json.Unmarshal([]byte(*result.SecretString), &secret); err != nil {
panic(err)
}
if _, err := tls.X509KeyPair([]byte(secret.PEM), []byte(secret.KEY)); err != nil {
panic(err)
}
}
英文:
I can confirm that a secret set by this command
aws secretsmanager update-secret --secret-id my-secret --secret-string '{"PEM":"-----BEGIN CERTIFICATE-----\n...\n...\n...\n-----END CERTIFICATE-----\n","KEY":"..."}'
works as expected (see the Go demo at the bottom of this answer).
And here is a simplified command that does the whole thing:
aws secretsmanager update-secret --secret-id -secret --secret-string "$(jq -n --arg cert "$(cat /path/to/cert/file)" --arg key "$(cat /path/to/key/file)" -c '{"PEM": $cert, "KEY": $key}')"
Here is a Go demo used to verify the uploaded content:
package main
import (
"context"
"crypto/tls"
"encoding/json"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
)
func main() {
secretName := "test1"
region := "ap-southeast-1"
config, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
panic(err)
}
svc := secretsmanager.NewFromConfig(config)
input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(secretName),
}
result, err := svc.GetSecretValue(context.TODO(), input)
if err != nil {
panic(err)
}
var secret struct {
PEM string `json:"PEM"`
KEY string `json:"KEY"`
}
{
}
if err := json.Unmarshal([]byte(*result.SecretString), &secret); err != nil {
panic(err)
}
if _, err := tls.X509KeyPair([]byte(secret.PEM), []byte(secret.KEY)); err != nil {
panic(err)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论