Aws-cli: aws kms decrypt Erro InvalidCiphertextException

Criado em 5 dez. 2014  ·  27Comentários  ·  Fonte: aws/aws-cli

Eu atualizei para a versão 1.6.6 do awscli hoje e o aws kms decrypt começou a falhar na descriptografia. Funciona em 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

Comentários muito úteis

Para aqueles que vierem a fazer isso mais tarde, para fazer isso _sem_ salvar o texto cifrado em um arquivo, você pode fazer:

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

Observação: como apontado por @hauntingEcho abaixo, <(cmd) não é compatível com POSIX, então se você estiver usando sh , não funcionará, mas bash e zsh funcionam bem.

Todos 27 comentários

Apenas algumas informações básicas sobre o que está acontecendo:

No 1.6.6 , corrigimos uma regressão na qual não codificávamos em base64 os tipos "blob" que antes codificávamos. Como resultado, agora você precisa especificar os bytes binários brutos para qualquer parâmetro marcado como um tipo de "blob" e, internamente, iremos codificá-lo automaticamente em base64 para você. Isso significa que, para a criptografia de chave de ida e volta, você precisará decodificar a base64 primeiro:

$ 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

Neste exemplo, também estou usando o prefixo fileb:// porque é um arquivo com conteúdo binário.

Acredito que o comportamento deve permanecer como está. Dado que o comportamento neste problema inicial dependia de uma regressão em 1.6.5 que foi corrigida em 1.6.6, realmente não podemos mudar o comportamento pré-existente, pois isso seria uma mudança significativa para os clientes. O snippet de exemplo acima é a maneira esperada de lidar com a entrada / saída binária no AWS CLI e, exceto por essa regressão recente, é a forma como esse comportamento sempre foi.

Obrigado pela atualização!

Na verdade, agora estou recebendo um erro semelhante ao problema # 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 Qual versão do AWS CLI você está usando? Acabei de tentar novamente na versão mais recente do AWS CLI (1.6.8) e não estou vendo este problema:

~ $ 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 agora funciona em 1.6.8. obrigado

@jamesls pessoalmente, acho que essa é uma IU incrivelmente ruim. Não sendo capaz de passar o mesmo texto cifrado para descriptografar que você obteve na criptografia? Se você não pode alterá-lo porque não deseja prejudicar os clientes existentes, ao menos dê a eles uma mensagem de erro melhor.

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

Nem me diz remotamente o que fazer para resolver o problema. Você pode detectar que a cifra é provavelmente Base64 e gerar um erro melhor e apontar para uma URL ou algo assim.

Ou, por que não passar um sinalizador adicional para decrypt para dizer "decodifique primeiro da base64"?

Para aqueles que vierem a fazer isso mais tarde, para fazer isso _sem_ salvar o texto cifrado em um arquivo, você pode fazer:

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

Observação: como apontado por @hauntingEcho abaixo, <(cmd) não é compatível com POSIX, então se você estiver usando sh , não funcionará, mas bash e zsh funcionam bem.

Re: comentário do @thegranddesign , no OS X pelo menos eu tive que usar 'D' maiúsculo para base64 . Por exemplo:

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

Decrypted: Hello world!

(Não sei por que recebo uma nova linha antes da linha Decrypted , mas não é grande coisa).

Isso funcionou para mim

#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

Tive um problema semelhante, mas o Node ajudou:

'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)));

outra observação sobre a solução de @thegranddesign - <(cmd) é um bashismo, não compatível com POSIX, então você precisará usar outra solução se bash não for uma opção.

Este é um bug incompreensivelmente estúpido que realmente deveria estar aberto até que seja realmente corrigido. É um anti-padrão gigante construir uma ferramenta que executa uma operação simétrica que usa um formato para saída e um formato completamente diferente (e incompatível) para entrada. Uma ferramenta simétrica que não pode consumir sua própria saída como entrada é QUEBRADA. Eu não me importo se ele está realmente funcionando como planejado, ainda está quebrado. A ferramenta deve gerar saída binária bruta por padrão se for dependente da entrada binária bruta, ou então deve ser capaz de consumir entrada codificada em base64 QUE GEROU sem especificar nenhuma etapa explícita de decodificação base64 ou parâmetros especiais que não foram também necessário para gerar essa saída (ou um anti-param se não usar o mesmo parâmetro exato). É além do absurdo que eu possa usar aws kms encrypt para gerar saída codificada em base64 de uma carga útil de criptografia codificada em base64 sem especificar QUALQUER uma dessas codificações em base64, mas então eu tenho que decodificar explicitamente em base64 tanto os dados criptografados quanto os dados descriptografados para obter de volta ao formulário que forneci em primeiro lugar. O fato de fazer isso também requer o uso de parâmetros de linha de comando que nem mesmo são documentados no nível dos subcomandos de criptografar e descriptografar torna muito mais difícil descobrir. Os usuários podem perder horas tentando descobrir como fazer a coisa mais óbvia que alguém pode querer fazer com um cliente de criptografia / descriptografia - criptografar e descriptografar uma string especificada em um parâmetro de linha de comando - e inteiramente porque a ferramenta tem um modo de operação interrompido em que as saídas não são compatíveis com as entradas, apesar do fato de que os dois subcomandos devem ser simétricos. Fechar isso sem consertar indica que você não tem absolutamente nenhuma preocupação com a usabilidade ou eficiência do desenvolvedor.

outro caminho para resolver isso (em oposição a novos sinalizadores, como @thegranddesign mencionado anos atrás) pode ser / não é um caractere base64 válido e não há uma maneira válida de especificar dados binários em json. Portanto:

  • se o parâmetro ciphertext-blob for válido de base 64, passe-o como base 64
  • se o parâmetro ciphertext-blob contiver / , analise como um caminho. fileb:// fazendo seu comportamento atual, file:// poderia ser codificado em b64.

Porém, de acordo com @ sgendler-stem - este tíquete está vinculado a todos os projetos em que trabalhei que usam KMS, porque é sempre um problema para alguém que tenta embarcar.

Este é um bug incompreensivelmente estúpido que realmente deveria estar aberto até que seja realmente corrigido. É um anti-padrão gigante construir uma ferramenta que executa uma operação simétrica que usa um formato para saída e um formato completamente diferente (e incompatível) para entrada. Uma ferramenta simétrica que não pode consumir sua própria saída como entrada é QUEBRADA. Eu não me importo se ele está realmente funcionando como planejado, ainda está quebrado. A ferramenta deve gerar saída binária bruta por padrão se for dependente da entrada binária bruta, ou então deve ser capaz de consumir entrada codificada em base64 QUE GEROU sem especificar nenhuma etapa explícita de decodificação base64 ou parâmetros especiais que não foram também necessário para gerar essa saída (ou um anti-param se não usar o mesmo parâmetro exato). É além do absurdo que eu possa usar aws kms encrypt para gerar saída codificada em base64 de uma carga útil de criptografia codificada em base64 sem especificar QUALQUER uma dessas codificações em base64, mas então eu tenho que decodificar explicitamente em base64 tanto os dados criptografados quanto os dados descriptografados para obter de volta ao formulário que forneci em primeiro lugar. O fato de fazer isso também requer o uso de parâmetros de linha de comando que nem mesmo são documentados no nível dos subcomandos de criptografar e descriptografar torna muito mais difícil descobrir. Os usuários podem perder horas tentando descobrir como fazer a coisa mais óbvia que alguém pode querer fazer com um cliente de criptografia / descriptografia - criptografar e descriptografar uma string especificada em um parâmetro de linha de comando - e inteiramente porque a ferramenta tem um modo de operação interrompido em que as saídas não são compatíveis com as entradas, apesar do fato de que os dois subcomandos devem ser simétricos. Fechar isso sem consertar indica que você não tem absolutamente nenhuma preocupação com a usabilidade ou eficiência do desenvolvedor.

Eu tenho que concordar totalmente com @ sgendler-stem - se o código gerar uma saída, ele deve ser, pelo menos , capaz de tomar isso como entrada.

No entanto, há mais do que isso. Se a criptografia for feita através do SDK - adicionando um estranho arn no final do arquivo criptografado, a CLI não será capaz de descriptografá-lo, mesmo após remover o não-base64 arn url. Isso está quebrado .

Concordo novamente. Isso tornou as coisas desnecessariamente frustrantes.

Isso está realmente fechado? Porque? Não acredito que já se passaram 4 anos desde que abriu e o único feedback parece ser alguém dizendo "funciona como planejado". Não, porra não; @sgendler-stem acertou no alvo, está completamente quebrado. Espero que a equipe responsável se sinta mal consigo mesma.

Enfrente as mesmas exceções:
botocore.errorfactory.InvalidCiphertextException: Ocorreu um erro (InvalidCiphertextException) ao chamar a operação de descriptografia:

Usado:
key = b64decode (chave)
resposta = client.decrypt (
CiphertextBlob = chave
)

Eu acho que isso não seria tão frustrante se a saída de encrypt , generate-data-key , etc, não chamasse o campo CiphertextBlob . Quando a entrada para decrypt também é chamada de --ciphertext-blob , não é nada intuitivo que esse blob de texto cifrado precise ser codificado de maneira diferente.

Se o sinalizador para decrypt tivesse um nome diferente, seria uma dica de que ele tem uma codificação diferente.

Há uma proposta de recurso para entrada codificada em base64 para descriptografar aqui https://github.com/aws/aws-cli/issues/2063

@ojitha

Como o kms sabe qual chave de criptografia usar para descriptografar, já que não estamos passando a ID da chave como um parâmetro durante a descriptografia.

@ arpit728 Acho que o CipherTextBlob retornado é específico sobre o KeyID de um determinado CMK.

Por favor, reabra este tíquete até que seja resolvido!

joguei muitas horas com isso até encontrar esse ingresso. existe alguma documentação oficial que declare exatamente como as coisas devem ser codificadas e transformadas entre criptografar e descriptografar?

Apenas algumas informações básicas sobre o que está acontecendo:

No 1.6.6 , corrigimos uma regressão na qual não codificávamos em base64 os tipos "blob" que antes codificávamos. Como resultado, agora você precisa especificar os bytes binários brutos para qualquer parâmetro marcado como um tipo de "blob" e, internamente, iremos codificá-lo automaticamente em base64 para você. Isso significa que, para a criptografia de chave de ida e volta, você precisará decodificar a base64 primeiro:

$ 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

Neste exemplo, também estou usando o prefixo fileb:// porque é um arquivo com conteúdo binário.

este exemplo retorna:

Ocorreu um erro (InvalidCiphertextException) ao chamar a operação Decrypt:
Descriptografado:

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

echo "Descriptografado: $ (aws kms decrypt --ciphertext-blob fileb: ./ arquivo criptografado --query Texto simples - texto de saída | base64 --decode)"
`
Tentei com o Ubuntu. Se alguém souber de uma documentação ou exemplos claros (link para um site ou algo assim) ficaria muito grato!

EDITAR: criptografar e descriptografar funcionando usando dicas deste artigo: https://dev.to/matchilling/pragmatically-storing-security-sensitive-data-using-aws-kms-5e5b

Para sua informação, o link acima não funciona, mas o artigo parece muito útil e está disponível aqui .

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

thomaswitt picture thomaswitt  ·  175Comentários

jamesls picture jamesls  ·  41Comentários

DanielLaberge picture DanielLaberge  ·  43Comentários

jamesls picture jamesls  ·  67Comentários

meonkeys picture meonkeys  ·  53Comentários