秘密管理器更新秘密 – 秘密字符串附加JSON编码

huangapple go评论88阅读模式
英文:

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)
	}
}

huangapple
  • 本文由 发表于 2023年5月23日 06:52:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76310332.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定