Aws-cli: aws kms déchiffre l'erreur InvalidCiphertextException

Créé le 5 déc. 2014  ·  27Commentaires  ·  Source: aws/aws-cli

Je suis passé à la version 1.6.6 d'awscli aujourd'hui et aws kms decrypt a commencé à échouer lors du déchiffrement. Cela fonctionne en 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

Commentaire le plus utile

Pour ceux qui y viendront plus tard, afin de faire cela _sans_ enregistrer le texte chiffré dans un fichier, vous pouvez faire :

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

Remarque : comme indiqué par @hauntingEcho ci-dessous, le <(cmd) n'est pas conforme à POSIX, donc si vous utilisez sh , cela ne fonctionnera pas, mais bash et zsh fonctionne bien.

Tous les 27 commentaires

Juste un peu d'informations sur ce qui se passe :

Dans 1.6.6 , nous avons corrigé une régression dans laquelle nous n'étions pas encodant en base64 les types de "blob" que nous encodions auparavant. En conséquence, vous devez maintenant spécifier les octets binaires bruts pour tout paramètre marqué comme un type "blob", et en interne, nous l'encoderons automatiquement en base64 pour vous. Cela signifie que pour le chiffrement de la clé aller-retour, vous devrez d'abord décoder la 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

Dans cet exemple, j'utilise également le préfixe fileb:// car il s'agit d'un fichier avec un contenu binaire.

Je pense que le comportement doit rester tel quel. Étant donné que le comportement de ce numéro initial reposait sur une régression dans la 1.6.5 qui a été corrigée dans la 1.6.6, nous ne pouvons vraiment pas changer le comportement préexistant, car ce serait un changement décisif pour les clients. L'exemple d'extrait ci-dessus est la manière attendue de gérer les entrées/sorties binaires dans l'AWS CLI, et à l'exception de cette régression récente, c'est la façon dont ce comportement a toujours été.

Merci pour la mise à jour!

En fait, je reçois maintenant une erreur similaire au problème #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 Quelle version de l'AWS CLI utilisez-vous ? Je viens de réessayer sur la dernière version de l'AWS CLI (1.6.8) et je ne vois pas ce problème :

~ $ 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 cela fonctionne maintenant en 1.6.8. Merci

@jamesls personnellement, je pense que c'est une interface utilisateur incroyablement mauvaise. Ne pas être en mesure de transmettre le même texte chiffré à déchiffrer que celui que vous avez obtenu à partir de chiffrer ? Si vous ne pouvez pas le changer parce que vous ne voulez pas casser les clients existants, donnez-leur au moins un meilleur message d'erreur.

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

Ne me dit même pas à distance quoi faire pour résoudre le problème. Vous pouvez détecter que le chiffrement est probablement Base64 et générer une meilleure erreur et les pointer vers une URL ou quelque chose.

Ou diable pourquoi ne pas passer un indicateur supplémentaire à decrypt pour dire "décoder d'abord ceci à partir de la base64" ?

Pour ceux qui y viendront plus tard, afin de faire cela _sans_ enregistrer le texte chiffré dans un fichier, vous pouvez faire :

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

Remarque : comme indiqué par @hauntingEcho ci-dessous, le <(cmd) n'est pas conforme à POSIX, donc si vous utilisez sh , cela ne fonctionnera pas, mais bash et zsh fonctionne bien.

Re: @thegranddesign « de commentaire , sur OS X au moins je devais utiliser un capital 'D' pour base64 . Par exemple:

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

Decrypted: Hello world!

(Je ne sais pas pourquoi j'obtiens une nouvelle ligne avant la ligne Decrypted , mais ce n'est pas grave).

Cela a fonctionné pour moi

#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

J'ai eu un problème similaire, mais Node m'a aidé :

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

une autre note sur la solution de @thegranddesign - <(cmd) est un bashism, non conforme à POSIX, vous devrez donc utiliser une autre solution si bash n'est pas une option.

Il s'agit d'un bug époustouflant qui devrait rester ouvert jusqu'à ce qu'il soit réellement corrigé. C'est un anti-modèle géant pour créer un outil qui effectue une opération symétrique qui utilise un format pour la sortie et un format complètement différent (et incompatible) pour l'entrée. Un outil symétrique qui ne peut pas consommer sa propre sortie en entrée est CASSÉ. Je m'en fiche si cela fonctionne réellement comme prévu, il est toujours cassé. L'outil doit soit générer une sortie binaire brute par défaut s'il dépend d'une entrée binaire brute, soit il devrait très bien pouvoir consommer l'entrée codée en base64 qu'il a générée sans spécifier d'étapes de décodage explicites en base64 ou de paramètres spéciaux qui ne l'étaient pas. également requis pour générer cette sortie (ou un anti-param s'il n'utilise pas exactement le même paramètre). Il est au-delà de l'absurde que je puisse utiliser aws kms encrypt pour générer une sortie codée en base64 d'une charge utile de cryptage codée en base64 sans spécifier AUCUN de ces codages en base64, mais je dois alors explicitement décoder en base64 à la fois les données cryptées ET les données décryptées afin d'obtenir il revient au formulaire que j'ai fourni en premier lieu. Le fait que cela nécessite également l'utilisation de paramètres de ligne de commande qui ne sont même pas documentés au niveau des sous-commandes de chiffrement et de déchiffrement le rend beaucoup plus difficile à comprendre. Les utilisateurs sont pratiquement assurés de perdre des heures à essayer de comprendre comment faire la chose la plus évidente que quelqu'un pourrait vouloir faire avec un client de chiffrement/déchiffrement - chiffrer puis déchiffrer une chaîne spécifiée dans un paramètre de ligne de commande - et entièrement parce que l'outil a un mode de fonctionnement cassé où les sorties ne sont pas compatibles avec les entrées malgré le fait que les deux sous-commandes sont censées être symétriques. Fermer ceci sans le réparer indique que vous n'avez absolument aucun souci pour la convivialité ou l'efficacité du développeur.

un autre chemin pour résoudre ce problème (par opposition aux nouveaux indicateurs, comme @thegranddesign mentionné il y a des années) pourrait être que / n'est pas un caractère base64 valide, et il n'y a aucun moyen valide de spécifier des données binaires dans json. Par conséquent:

  • si le paramètre ciphertext-blob est valide en base-64, transmettez-le en base 64
  • si le paramètre ciphertext-blob contient / , analysez-le comme un chemin. fileb:// faisant son comportement actuel, file:// pourrait être encodé en b64.

D'accord avec @sgendler-stem cependant - ce ticket est lié à chaque projet sur lequel j'ai travaillé et qui utilise KMS, car c'est toujours un problème pour quelqu'un qui essaie de monter à bord.

Il s'agit d'un bug époustouflant qui devrait rester ouvert jusqu'à ce qu'il soit réellement corrigé. C'est un anti-modèle géant pour créer un outil qui effectue une opération symétrique qui utilise un format pour la sortie et un format complètement différent (et incompatible) pour l'entrée. Un outil symétrique qui ne peut pas consommer sa propre sortie en entrée est CASSÉ. Je m'en fiche si cela fonctionne réellement comme prévu, il est toujours cassé. L'outil doit soit générer une sortie binaire brute par défaut s'il dépend d'une entrée binaire brute, soit il devrait très bien pouvoir consommer l'entrée codée en base64 qu'il a générée sans spécifier d'étapes de décodage explicites en base64 ou de paramètres spéciaux qui ne l'étaient pas. également requis pour générer cette sortie (ou un anti-param s'il n'utilise pas exactement le même paramètre). Il est au-delà de l'absurde que je puisse utiliser aws kms encrypt pour générer une sortie codée en base64 d'une charge utile de cryptage codée en base64 sans spécifier AUCUN de ces codages en base64, mais je dois alors explicitement décoder en base64 à la fois les données cryptées ET les données décryptées afin d'obtenir il revient au formulaire que j'ai fourni en premier lieu. Le fait que cela nécessite également l'utilisation de paramètres de ligne de commande qui ne sont même pas documentés au niveau des sous-commandes de chiffrement et de déchiffrement le rend beaucoup plus difficile à comprendre. Les utilisateurs sont pratiquement assurés de perdre des heures à essayer de comprendre comment faire la chose la plus évidente que quelqu'un pourrait vouloir faire avec un client de chiffrement/déchiffrement - chiffrer puis déchiffrer une chaîne spécifiée dans un paramètre de ligne de commande - et entièrement parce que l'outil a un mode de fonctionnement cassé où les sorties ne sont pas compatibles avec les entrées malgré le fait que les deux sous-commandes sont censées être symétriques. Fermer ceci sans le réparer indique que vous n'avez absolument aucun souci pour la convivialité ou l'efficacité du développeur.

Je suis entièrement d'accord avec @sgendler-stem - si le code génère une sortie, il devrait au moins être capable de la prendre en entrée.

Cependant, il y a plus à cela. Si le chiffrement est effectué via le SDK - en ajoutant un arn étrange à la fin du fichier chiffré, la CLI ne pourra pas le déchiffrer, même après avoir supprimé le arn non-base64 URL. C'est juste cassé .

D'accord à nouveau. Cela a rendu les choses inutilement frustrantes.

C'est vraiment fermé ? Pourquoi? Je ne peux pas croire que cela fait 4 ans que cela a ouvert et le seul retour semble être quelqu'un qui dit "fonctionne comme prévu". Non, ce n'est pas le cas ; @sgendler-stem est juste sur la cible, c'est complètement cassé. J'espère que l'équipe responsable se sent mal dans sa peau.

Faites face aux mêmes exceptions :
botocore.errorfactory.InvalidCiphertextException : une erreur s'est produite (InvalidCiphertextException) lors de l'appel de l'opération Decrypt :

Utilisé:
clé = b64decode(clé)
réponse = client.decrypt(
CiphertextBlob=clé
)

Je pense que ce ne serait pas si frustrant si la sortie de encrypt , generate-data-key , etc n'appelait pas le champ CiphertextBlob . Lorsque l'entrée de decrypt est également appelée --ciphertext-blob , il n'est pas du tout intuitif que ce blob de texte chiffré doive être encodé différemment.

Si le drapeau à decrypt avait un nom différent, ce serait un indice qu'il a un codage différent.

Il y a une proposition de fonctionnalité pour l'entrée codée en base64 à déchiffrer ici https://github.com/aws/aws-cli/issues/2063

@ojitha

Comment kms sait-il quelle clé de chiffrement utiliser pour le déchiffrement, puisque nous ne transmettons pas key-id comme paramètre lors du déchiffrement.

@ arpit728 Je pense que CipherTextBlob renvoyé concerne le KeyID d'une clé CMK particulière.

Veuillez rouvrir ce ticket jusqu'à ce qu'il soit résolu !

joué trop d'heures avec ça jusqu'à ce que je trouve ce ticket. existe-t-il une documentation officielle indiquant comment exactement les choses doivent être codées et transformées entre le cryptage et le décryptage ?

Juste un peu d'informations sur ce qui se passe :

Dans 1.6.6 , nous avons corrigé une régression dans laquelle nous n'étions pas encodant en base64 les types de "blob" que nous encodions auparavant. En conséquence, vous devez maintenant spécifier les octets binaires bruts pour tout paramètre marqué comme un type "blob", et en interne, nous l'encoderons automatiquement en base64 pour vous. Cela signifie que pour le chiffrement de la clé aller-retour, vous devrez d'abord décoder la 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

Dans cet exemple, j'utilise également le préfixe fileb:// car il s'agit d'un fichier avec un contenu binaire.

cet exemple renvoie :

Une erreur s'est produite (InvalidCiphertextException) lors de l'appel de l'opération Decrypt :
Décrypté :

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

echo "Déchiffré : $(aws kms decrypt --ciphertext-blob fileb:./encrypted-file --query Plaintext --output text | base64 --decode)"
`
J'ai essayé avec Ubuntu. Si quelqu'un connaît une documentation claire ou des exemples (lien vers un site ou quelque chose), je lui en serais très reconnaissant !

EDIT: chiffrez et déchiffrez en utilisant les astuces de cet article: https://dev.to/matchilling/pragmatically-storing-security-sensible-data-using-aws-kms-5e5b

Pour info, le lien ci-dessus ne fonctionne pas, mais l'article semble assez utile et est disponible ici .

Cette page vous a été utile?
0 / 5 - 0 notes