Aws-cli: aws kms descifra el error de excepción InvalidCiphertextException

Creado en 5 dic. 2014  ·  27Comentarios  ·  Fuente: aws/aws-cli

Actualicé a la versión 1.6.6 de awscli hoy y aws kms decrypt comenzó a fallar en el descifrado. Funciona 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

Comentario más útil

Para aquellos que lleguen a esto más tarde, para hacer esto _sin_ guardar el texto cifrado en un archivo, pueden hacer:

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

Nota: como lo señala @hauntingEcho a continuación, <(cmd) no es compatible con POSIX, por lo que si está usando sh , no funcionará, pero bash y zsh funciona bien.

Todos 27 comentarios

Solo un poco de información de fondo sobre lo que está sucediendo:

En 1.6.6 , regresión en la que no estábamos codificando en base64 los tipos de "blob" que habíamos estado codificando anteriormente. Como resultado, ahora necesita especificar los bytes binarios sin procesar para cualquier parámetro marcado como un tipo "blob", e internamente lo codificaremos automáticamente en base64. Esto significa que para el cifrado de clave de ida y vuelta, primero deberá decodificar 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

En este ejemplo, también estoy usando el prefijo fileb:// porque es un archivo con contenido binario.

Creo que el comportamiento debería permanecer como está. Dado que el comportamiento en este número inicial se basó en una regresión en 1.6.5 que se corrigió en 1.6.6, realmente no podemos cambiar el comportamiento preexistente, ya que sería un cambio importante para los clientes. El fragmento de ejemplo anterior es la forma esperada de manejar la entrada / salida binaria en la AWS CLI y, a excepción de esta regresión reciente, es la forma en que este comportamiento siempre ha sido.

¡Gracias por la actualización!

De hecho, ahora recibo un error similar al número 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 ¿Qué versión de la AWS CLI está utilizando? Intenté nuevamente con la última versión de AWS CLI (1.6.8) y no veo 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 funciona ahora en 1.6.8. Gracias

@jamesls personalmente, creo que esta es una interfaz de usuario increíblemente mala. ¿No puede pasar el mismo texto cifrado al descifrado que obtuvo del cifrado? Si no puede cambiarlo porque no quiere romper con los clientes existentes, al menos envíeles un mensaje de error mejor.

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

Ni siquiera me dice remotamente qué hacer para solucionar el problema. Podría detectar que el cifrado es probablemente Base64 y generar un error mejor y apuntarlos a una URL o algo así.

O diablos, ¿por qué no pasar una bandera adicional a decrypt para decir "decodificar esto desde base64 primero"?

Para aquellos que lleguen a esto más tarde, para hacer esto _sin_ guardar el texto cifrado en un archivo, pueden hacer:

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

Nota: como lo señala @hauntingEcho a continuación, <(cmd) no es compatible con POSIX, por lo que si está usando sh , no funcionará, pero bash y zsh funciona bien.

Re: comentario de @thegranddesign , en OS X al menos tuve que usar una 'D' mayúscula por base64 . P.ej:

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

Decrypted: Hello world!

(No estoy seguro de por qué obtengo una nueva línea antes de la línea Decrypted , pero no es gran cosa).

Esto funcionó para mi

#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

Tuve un problema similar, pero Node ayudó:

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

otra nota sobre la solución de @thegranddesign : <(cmd) es un bashism, no compatible con POSIX, por lo que deberá usar otra solución si bash no es una opción.

Este es un error increíblemente tonto que realmente debería estar abierto hasta que se solucione. Es un anti-patrón gigante para construir una herramienta que realiza una operación simétrica que usa un formato para la salida y un formato completamente diferente (e incompatible) para la entrada. Una herramienta simétrica que no puede consumir su propia salida como entrada está ROTA. No me importa si realmente está funcionando como se esperaba, todavía está roto. La herramienta debe generar una salida binaria sin procesar de forma predeterminada si depende de una entrada binaria sin procesar, o bien debería poder consumir una entrada codificada en base64 QUE GENERÓ sin especificar ningún paso explícito de decodificación de base64 o parámetros especiales que no lo fueran también se requiere para generar esa salida (o un anti-param si no usa exactamente el mismo param). Es más que absurdo que pueda usar el cifrado de aws kms para generar una salida codificada en base64 de una carga útil de cifrado codificada en base64 sin especificar TANTO de esas codificaciones en base64, pero luego tengo que decodificar explícitamente en base64 tanto los datos cifrados como los datos descifrados para obtener volver al formulario que proporcioné en primer lugar. El hecho de que hacerlo también requiere el uso de parámetros de línea de comandos que ni siquiera están documentados en el nivel de los subcomandos de cifrado y descifrado hace que sea mucho más difícil de descifrar. Los usuarios tienen casi la garantía de perder horas tratando de averiguar cómo hacer la cosa más obvia que alguien podría querer hacer con un cliente de cifrado / descifrado: cifrar y luego descifrar una cadena especificada en un parámetro de línea de comando, y completamente porque la herramienta tiene un modo de funcionamiento roto en el que las salidas no son compatibles con las entradas a pesar de que se supone que los dos subcomandos son simétricos. Cerrar esto sin arreglarlo indica que no tiene absolutamente ninguna preocupación por la usabilidad o la eficiencia del desarrollador.

otra ruta para resolver esto (a diferencia de las nuevas banderas, como @thegranddesign mencionó hace años) podría ser que / no es un carácter base64 válido, y no hay una forma válida de especificar datos binarios en json. Por lo tanto:

  • si el parámetro ciphertext-blob es base-64 válido, páselo como base 64
  • si el parámetro ciphertext-blob contiene / , analícelo como una ruta. fileb:// haciendo su comportamiento actual, file:// podría estar codificado en b64.

Sin embargo, estoy de acuerdo con @ sgendler-stem: este ticket está vinculado en todos los proyectos en los que he trabajado y que usan KMS, porque siempre es un problema para alguien que intenta participar.

Este es un error increíblemente tonto que realmente debería estar abierto hasta que se solucione. Es un anti-patrón gigante para construir una herramienta que realiza una operación simétrica que usa un formato para la salida y un formato completamente diferente (e incompatible) para la entrada. Una herramienta simétrica que no puede consumir su propia salida como entrada está ROTA. No me importa si realmente está funcionando como se esperaba, todavía está roto. La herramienta debe generar una salida binaria sin procesar de forma predeterminada si depende de una entrada binaria sin procesar, o bien debería poder consumir una entrada codificada en base64 QUE GENERÓ sin especificar ningún paso explícito de decodificación de base64 o parámetros especiales que no lo fueran también se requiere para generar esa salida (o un anti-param si no usa exactamente el mismo param). Es más que absurdo que pueda usar el cifrado de aws kms para generar una salida codificada en base64 de una carga útil de cifrado codificada en base64 sin especificar TANTO de esas codificaciones en base64, pero luego tengo que decodificar explícitamente en base64 tanto los datos cifrados como los datos descifrados para obtener volver al formulario que proporcioné en primer lugar. El hecho de que hacerlo también requiere el uso de parámetros de línea de comandos que ni siquiera están documentados en el nivel de los subcomandos de cifrado y descifrado hace que sea mucho más difícil de descifrar. Los usuarios tienen casi la garantía de perder horas tratando de averiguar cómo hacer la cosa más obvia que alguien podría querer hacer con un cliente de cifrado / descifrado: cifrar y luego descifrar una cadena especificada en un parámetro de línea de comando, y completamente porque la herramienta tiene un modo de funcionamiento roto en el que las salidas no son compatibles con las entradas a pesar de que se supone que los dos subcomandos son simétricos. Cerrar esto sin arreglarlo indica que no tiene absolutamente ninguna preocupación por la usabilidad o la eficiencia del desarrollador.

Tengo que estar completamente de acuerdo con @ sgendler-stem: si el código genera una salida, al menos debería poder tomarla como entrada.

Sin embargo, hay más en eso. Si la encriptación se realiza a través del SDK, agregando un arn extraño al final del archivo encriptado, la CLI no podrá desencriptarlo, incluso después de eliminar el no base64 arn url. Esto simplemente está roto .

De acuerdo de nuevo. Esto ha hecho que las cosas sean innecesariamente frustrantes.

¿Esto está realmente cerrado? ¿Por qué? No puedo creer que hayan pasado 4 años desde que se abrió y el único comentario parece ser alguien que dice "funciona según lo previsto". No, joder, no lo hace; @ sgendler-stem está justo en el objetivo, esto está completamente roto. Espero que el equipo responsable se sienta mal consigo mismo.

Enfréntate a las mismas excepciones:
botocore.errorfactory.InvalidCiphertextException: Se produjo un error (InvalidCiphertextException) al llamar a la operación Decrypt:

Usó:
key = b64decode (clave)
respuesta = cliente.decrypt (
CiphertextBlob = clave
)

Creo que esto no sería tan frustrante si la salida de encrypt , generate-data-key , etc. no llamara al campo CiphertextBlob . Cuando la entrada a decrypt también se llama --ciphertext-blob , no es intuitivo que este blob de texto cifrado deba codificarse de manera diferente.

Si la bandera de decrypt tuviera un nombre diferente, sería un indicio de que tiene una codificación diferente.

Hay una propuesta de función para la entrada codificada en base64 para descifrar aquí https://github.com/aws/aws-cli/issues/2063

@ojitha

¿Cómo sabe kms qué clave de cifrado usar para el descifrado, ya que no estamos pasando key-id como parámetro mientras desciframos?

@ arpit728 Creo que CipherTextBlob devuelto es particular sobre el KeyID de una CMK en particular.

¡Vuelva a abrir este ticket hasta que se resuelva!

Jugué demasiadas horas con esto hasta que encontré este boleto. ¿Existe alguna documentación oficial que indique cómo exactamente se deben codificar y transformar las cosas entre cifrar y descifrar?

Solo un poco de información de fondo sobre lo que está sucediendo:

En 1.6.6 , regresión en la que no estábamos codificando en base64 los tipos de "blob" que habíamos estado codificando anteriormente. Como resultado, ahora necesita especificar los bytes binarios sin procesar para cualquier parámetro marcado como un tipo "blob", e internamente lo codificaremos automáticamente en base64. Esto significa que para el cifrado de clave de ida y vuelta, primero deberá decodificar 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

En este ejemplo, también estoy usando el prefijo fileb:// porque es un archivo con contenido binario.

este ejemplo devuelve:

Ocurrió un error (InvalidCiphertextException) al llamar a la operación Decrypt:
Descifrado:

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

echo "Descifrado: $ (aws kms descifrar --ciphertext-blob fileb: ./ encrypted-file --query Plaintext --output text | base64 --decode)"
'
Probado con ubuntu. Si alguien conoce una documentación clara o ejemplos (enlace a un sitio o algo así), ¡estaría muy agradecido!

EDITAR: cifró y descifró el trabajo usando los consejos de este artículo: https://dev.to/matchilling/pragmatic-storing-security-sensitive-data-using-aws-kms-5e5b

Para su información, el enlace anterior no funciona, pero el artículo parece bastante útil y está disponible aquí .

¿Fue útil esta página
0 / 5 - 0 calificaciones