Aws-cli: aws kms 解密 InvalidCiphertextException 错误

创建于 2014-12-05  ·  27评论  ·  资料来源: aws/aws-cli

我今天升级到 awscli 的 1.6.6 版,aws kms 解密开始失败。 它适用于 1.6.5。

$> aws --version
aws-cli/1.6.6 Python/2.7.6 Darwin/13.4.0

$> python -V
Python 2.7.6

$> aws kms encrypt --key-id REDACTED --plaintext foo 
{
    "KeyId": "arn:aws:kms:us-east-1:REDACTED:key/REDACTED", 
    "CiphertextBlob": "CiDdiD7jljnCzXlfZUp27Y4LDY+QJa2Zqcw/7+ihfBDo7hKKAQEBAgB43Yg+45Y5ws15X2VKdu2OCw2PkCWtmanMP+/ooXwQ6O4AAABhMF8GCSqGSIb3DQEHBqBSMFACAQAwSwYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAwVt2CzbGDR2nUwszQCARCAHgdJ4aHQ4i7TMzBN6XlKcC73oilECgep+basamtnXQ=="
}

$> aws kms decrypt --ciphertext-blob CiDdiD7jljnCzXlfZUp27Y4LDY+QJa2Zqcw/7+ihfBDo7hKKAQEBAgB43Yg+45Y5ws15X2VKdu2OCw2PkCWtmanMP+/ooXwQ6O4AAABhMF8GCSqGSIb3DQEHBqBSMFACAQAwSwYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAwVt2CzbGDR2nUwszQCARCAHgdJ4aHQ4i7TMzBN6XlKcC73oilECgep+basamtnXQ==

A client error (InvalidCiphertextException) occurred when calling the Decrypt operation: None

$> pip freeze                                       
Babel==1.3
Fabric==1.10.0
Jinja2==2.7.3
MarkupSafe==0.23
Pillow==2.6.1
PyChef==0.2.3
PyYAML==3.11
Pygments==2.0.1
Sphinx==1.2.3
argparse==1.2.1
astroid==1.2.1
awscli==1.6.6
bcdoc==0.12.2
binaryornot==0.3.0
boto==2.34.0
botocore==0.77.0
box.py==1.2.8
cffi==0.8.6
cliff==1.8.0
cmd2==0.6.7
colorama==0.2.5
cookiecutter==0.8.0
coverage==3.7.1
cryptography==0.6.1
decorator==3.4.0
docutils==0.12
dogapi==1.8.5
ecdsa==0.11
futures==2.2.0
httplib2==0.9
httpretty==0.8.3
iso8601==0.1.10
jmespath==0.5.0
jsonpatch==1.9
jsonpointer==1.5
jsonschema==2.4.0
kazoo==2.0
keyring==4.0
logilab-common==0.63.0
lxml==3.4.0
mock==1.0.1
mockito==0.5.2
netaddr==0.7.12
nose==1.3.4
numpy==1.9.1
oath==1.2
oslo.config==1.4.0
oslo.i18n==1.0.0
oslo.serialization==1.0.0
oslo.utils==1.0.0
paramiko==1.15.1
pbr==0.10.0
prettytable==0.7.2
pyOpenSSL==0.14
pyasn1==0.1.7
pycparser==2.10
pycrypto==2.6.1
pylint==1.3.1
pyparsing==2.0.3
python-ceilometerclient==1.0.12
python-cinderclient==1.1.1
python-dateutil==2.3
python-glanceclient==0.14.2
python-heatclient==0.2.12
python-keystoneclient==0.11.2
python-neutronclient==2.3.9
python-novaclient==2.20.0
python-openstackclient==0.4.1
python-swiftclient==2.3.1
python-troveclient==1.0.7
pytz==2014.9
qrcode==5.1
requests==2.4.3
rsa==3.1.2
scipy==0.14.0
simplejson==3.6.5
six==1.8.0
stevedore==1.1.0
urllib3==1.9.1
virtualenv==1.11.6
warlock==1.1.0
wsgiref==0.1.2

最有用的评论

对于那些后来来到这里的人,为了做到这一点,_没有_将密文保存到一个文件中,你可以这样做:

aws kms decrypt --ciphertext-blob fileb://<(echo 'ciphertext' | base64 -d)

注意:正如下面@hauntingEcho所指出的, <(cmd)不符合 POSIX 标准,因此如果您使用sh ,它将不起作用,但bashzsh工作正常。

所有27条评论

只是关于正在发生的事情的一些背景信息:

1.6.6 中,我们修复了一个回归,其中我们没有对我们之前编码的“blob”类型进行 base64 编码。 因此,您现在需要为标记为“blob”类型的任何参数指定原始二进制字节,并且在内部我们将自动为您进行 base64 编码。 这意味着要进行往返密钥加密,您需要先解码 base64:

$ aws kms encrypt --key-id <key-id> --plaintext "abcd" --query CiphertextBlob --output text | base64 -D > /tmp/encrypted-file
$ echo "Decrypted: $(aws kms decrypt --ciphertext-blob fileb:///tmp/encrypted-file --query Plaintext --output text | base64 -D)"
Decrypted: abcd

在这个例子中,我还使用了fileb://前缀,因为它是一个包含二进制内容的文件。

我相信行为应该保持原样。 鉴于此初始问题中的行为依赖于 1.6.5 中在 1.6.6 中修复的回归,我们确实无法更改预先存在的行为,因为这对客户来说将是一个重大变化。 上面的示例片段是在 AWS CLI 中处理二进制输入/输出的预期方式,除了最近的回归之外,一直是这种行为的方式。

感谢更新!

实际上,现在我收到类似于问题 #1001 的错误

$> aws kms encrypt --key-id $KMS_KEY_ID --plaintext "abcd" --query CiphertextBlob --output text | base64 -D > /tmp/encrypted-file

$> echo "Decrypted: $(aws kms decrypt --ciphertext-blob fileb:///tmp/encrypted-file --query Plaintext --output text | base64 -D)"

'ascii' codec can't decode byte 0xdd in position 2: ordinal not in range(128)
Decrypted: 

@mtougeron您使用的是什么版本的 AWS CLI? 我刚刚在最新版本的 AWS CLI (1.6.8) 上再次尝试,但我没有看到这个问题:

~ $ aws kms encrypt --key-id $AWS_KEY_ID --plaintext "abcd" --query CiphertextBlob --output text | base64 -D > /tmp/encrypted-file
~ $ hexdump -C /tmp/encrypted-file
00000000  0a 20 e1 68 92 dc 42 40  fe 07 80 ca f6 54 1c 68  |. [email protected]|
00000010  e2 45 80 bb c3 e0 2a 2f  91 50 7c ac c3 02 9b c9  |.E....*/.P|.....|
00000020  a8 b3 12 8b 01 01 01 02  00 78 e1 68 92 dc 42 40  |.........x.h..B@|
00000030  fe 07 80 ca f6 54 1c 68  e2 45 80 bb c3 e0 2a 2f  |.....T.h.E....*/|
00000040  91 50 7c ac c3 02 9b c9  a8 b3 00 00 00 62 30 60  |.P|..........b0`|
00000050  06 09 2a 86 48 86 f7 0d  01 07 06 a0 53 30 51 02  |..*.H.......S0Q.|
00000060  01 00 30 4c 06 09 2a 86  48 86 f7 0d 01 07 01 30  |..0L..*.H......0|
00000070  1e 06 09 60 86 48 01 65  03 04 01 2e 30 11 04 0c  |...`.H.e....0...|
00000080  41 de f2 2a a6 c5 38 ef  8a 52 54 92 02 01 10 80  |A..*..8..RT.....|
00000090  1f 2e 01 90 65 7a 21 8c  dd 05 e4 4d 09 64 85 c4  |....ez!....M.d..|
000000a0  33 e3 3d e9 ce 33 6b e9  00 93 ec e5 54 33 8b 3b  |3.=..3k.....T3.;|
000000b0
~ $ echo "Decrypted: $(aws kms decrypt --ciphertext-blob fileb:///tmp/encrypted-file --query Plaintext --output text | base64 -D)"
Decrypted: abcd
~ $ aws --version
aws-cli/1.6.8 Python/2.7.7 Darwin/13.4.0

@jamesls现在可以在 1.6.8 中使用了。 谢谢

@jamesls我个人认为这是非常糟糕的用户界面。 无法将相同的密文传递给您从加密中获得的解密? 如果因为不想破坏现有客户而无法更改它,至少给他们一个更好的错误信息。

A client error (InvalidCiphertextException) occurred when calling the Decrypt operation: None

甚至没有远程告诉我如何解决问题。 您可以检测到密码可能是 Base64 并输出更好的错误并将它们指向 URL 或其他内容。

或者为什么不向decrypt传递一个额外的标志来说“首先从 base64 解码”?

对于那些后来来到这里的人,为了做到这一点,_没有_将密文保存到一个文件中,你可以这样做:

aws kms decrypt --ciphertext-blob fileb://<(echo 'ciphertext' | base64 -d)

注意:正如下面@hauntingEcho所指出的, <(cmd)不符合 POSIX 标准,因此如果您使用sh ,它将不起作用,但bashzsh工作正常。

回复: @thegranddesign评论,至少在 OS X 上,我必须为base64使用大写的“D”。 例如:

$ echo "Decrypted: $(aws kms decrypt --ciphertext-blob fileb://<(echo $ENCRYPTED_DATA | base64 -D) --query Plaintext --output text | base64 -D)"

Decrypted: Hello world!

(不知道为什么我在Decrypted行之前得到一个换行符,但没什么大不了的)。

这对我有用

#encrypt the password: TestReadWrite text in the test.txt file
aws kms encrypt --key-id cfc7acf7-4f20-49c3-aa11-8be4cdc3291d --plaintext fileb://test.txt --output text | base64 --decode > out.txt

#decrypt the password: TestReadWrite
aws kms decrypt  --ciphertext-blob fileb://out.txt --output text --query Plaintext | base64 --decode

我有一个类似的问题,但 Node 有帮助:

'use strict';

const KMS = require('aws-sdk').KMS;
const fs = require('fs');

const kms = new KMS({
  apiVersion: '2014-11-01',
  // region: 'eu-west-1'
});

function encrypt(params) {
  return kms.encrypt(params).promise();
}

const arn = 'arn:aws:kms:xxx';

encrypt({
  KeyId: arn,
  Plaintext: fs.readFileSync('/path/to/key.pem')
})
.then(data => fs.writeFileSync('/path/to/key.json', JSON.stringify(data)));

关于@thegranddesign解决方案的另一个说明 - <(cmd)是一种bashism,不符合POSIX,因此如果bash 不是一个选项,您将需要使用另一种解决方案。

这是一个令人难以置信的愚蠢错误,在实际修复之前,它确实应该保持开放状态。 构建一个执行对称操作的工具是一个巨大的反模式,该工具使用一种输出格式和一种完全不同(且不兼容)的输入格式。 不能将自己的输出用作输入的对称工具是 BROKEN。 我不在乎它是否真的按预期工作,它仍然坏了。 如果该工具依赖于原始二进制输入,则该工具应该默认生成原始二进制输出,否则它应该能够使用它生成的 base64 编码输入,而无需指定任何明确的 base64 解码步骤或未指定的特殊参数也需要以生成该输出(或反参数,如果它不使用相同的确切参数)。 我可以使用 aws kms encrypt 生成 base64 编码的加密有效负载的 base64 编码输出而不指定那些 base64 编码中的任何一个,这简直荒谬,但是我必须显式地对加密数据和解密数据进行 base64 解码以获得它回到我最初提供的表格。 这样做还需要使用命令行参数,而这些参数甚至没有在 encrypt 和decrypt 子命令级别进行记录,这使得弄清楚这一点变得更加困难。 用户几乎肯定会浪费数小时试图弄清楚如何使用加密/解密客户端来完成某人可能想要做的最明显的事情 - 加密然后解密命令行参数中指定的字符串 - 完全是因为该工具尽管两个子命令应该是对称的,但它的操作模式已损坏,其中输出与输入不兼容。 关闭它而不修复它表明您完全不关心可用性或开发人员效率。

解决此问题的另一条路径(与@thegranddesign 多年前提到的新标志相反)可能是/不是有效的 base64 字符,并且没有有效的方法在 json 中指定二进制数据。 所以:

  • 如果 ciphertext-blob 参数是有效的 base-64,则将其作为 base-64 传递
  • 如果 ciphertext-blob 参数包含/ ,则解析为路径。 fileb://执行其当前行为, file://可以是 b64 编码的。

不过同意@sgendler-stem - 这张票在我参与的每个使用 KMS 的项目中都有链接,因为对于试图加入的人来说,这总是一个问题。

这是一个令人难以置信的愚蠢错误,在实际修复之前,它确实应该保持开放状态。 构建一个执行对称操作的工具是一个巨大的反模式,该工具使用一种输出格式和一种完全不同(且不兼容)的输入格式。 不能将自己的输出用作输入的对称工具是 BROKEN。 我不在乎它是否真的按预期工作,它仍然坏了。 如果该工具依赖于原始二进制输入,则该工具应该默认生成原始二进制输出,否则它应该能够使用它生成的 base64 编码输入,而无需指定任何明确的 base64 解码步骤或未指定的特殊参数也需要以生成该输出(或反参数,如果它不使用相同的确切参数)。 我可以使用 aws kms encrypt 生成 base64 编码的加密有效负载的 base64 编码输出而不指定那些 base64 编码中的任何一个,这简直荒谬,但是我必须显式地对加密数据和解密数据进行 base64 解码以获得它回到我最初提供的表格。 这样做还需要使用命令行参数,而这些参数甚至没有在 encrypt 和decrypt 子命令级别进行记录,这使得弄清楚这一点变得更加困难。 用户几乎肯定会浪费数小时试图弄清楚如何使用加密/解密客户端来完成某人可能想要做的最明显的事情 - 加密然后解密命令行参数中指定的字符串 - 完全是因为该工具尽管两个子命令应该是对称的,但它的操作模式已损坏,其中输出与输入不兼容。 关闭它而不修复它表明您完全不关心可用性或开发人员效率。

我必须完全同意@sgendler-stem - 如果代码生成输出,它至少应该能够将其作为输入。

然而,还有更多。 如果 ecryption 是通过 SDK 完成的——在加密文件的末尾添加一个奇怪的arn ,CLI 将无法解密它,即使删除了非 base64 arn网址。 这只是坏了

再次同意。 这让事情变得不必要地令人沮丧。

这居然关门了? 为什么? 我不敢相信它已经开放 4 年了,唯一的反馈似乎是有人说“按预期工作”。 不,他妈的没有; @sgendler-stem 是正确的,这完全坏了。 希望负责的团队对自己感觉不好。

面对同样的例外:
botocore.errorfactory.InvalidCiphertextException:调用解密操作时发生错误(InvalidCiphertextException):

用过的:
密钥 = b64decode(key)
响应 = client.decrypt(
CiphertextBlob=key
)

我认为如果encryptgenerate-data-key等的输出没有调用字段CiphertextBlob这不会那么令人沮丧。 当decrypt的输入也称为--ciphertext-blob ,这个密文 blob 需要以不同方式编码是完全不直观的。

如果decrypt的标志具有不同的名称,则暗示它具有不同的编码。

这里有一个 base64 编码输入的功能提案可以解密https://github.com/aws/aws-cli/issues/2063

@ojitha

kms 如何知道使用哪个加密密钥进行解密,因为我们在解密时没有将 key-id 作为参数传递。

@arpit728我认为返回的 CipherTextBlob 与特定 CMK 的 KeyID 相关。

请重新打开此票,直到解决为止!

玩了太多小时,直到找到这张票。 是否有任何官方文档说明应该如何在加密和解密之间对事物进行编码和转换?

只是关于正在发生的事情的一些背景信息:

1.6.6 中,我们修复了一个回归,其中我们没有对我们之前编码的“blob”类型进行 base64 编码。 因此,您现在需要为标记为“blob”类型的任何参数指定原始二进制字节,并且在内部我们将自动为您进行 base64 编码。 这意味着要进行往返密钥加密,您需要先解码 base64:

$ aws kms encrypt --key-id <key-id> --plaintext "abcd" --query CiphertextBlob --output text | base64 -D > /tmp/encrypted-file
$ echo "Decrypted: $(aws kms decrypt --ciphertext-blob fileb:///tmp/encrypted-file --query Plaintext --output text | base64 -D)"
Decrypted: abcd

在这个例子中,我还使用了fileb://前缀,因为它是一个包含二进制内容的文件。

此示例返回:

调用解密操作时发生错误(InvalidCiphertextException):
解密:

`aws kms encrypt --key-id arn:aws:kms:eu-west-1werwerwjl:key/xxxyyyy --plaintext "abcd" --query CiphertextBlob --output text | base64 -d > ./encrypted-file

echo "解密: $(aws kms 解密 --ciphertext-blob fileb:./encrypted-file --query Plaintext --output text | base64 --decode)"
`
用 ubuntu 试过。 如果有人知道清晰的文档或示例(链接到网站或其他内容),我将不胜感激!

编辑:使用本文中的提示进行加密和解密工作: https :

仅供参考,上面的链接不起作用,但这篇文章似乎很有用,可以在这里找到

此页面是否有帮助?
0 / 5 - 0 等级