Aws-cli: aws kms mendekripsi kesalahan InvalidCiphertextException

Dibuat pada 5 Des 2014  ·  27Komentar  ·  Sumber: aws/aws-cli

Saya memutakhirkan ke versi 1.6.6 dari awscli hari ini dan dekripsi aws kms mulai gagal pada dekripsi. Ia bekerja di 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

Komentar yang paling membantu

Bagi mereka yang datang ke sini nanti, untuk melakukan ini _tanpa_ menyimpan ciphertext ke file, Anda dapat melakukan:

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

Catatan: seperti yang ditunjukkan oleh @hauntingEcho di bawah, <(cmd) tidak sesuai dengan POSIX jadi jika Anda menggunakan sh , itu tidak akan berfungsi, tetapi bash dan zsh berfungsi dengan baik.

Semua 27 komentar

Hanya sedikit info latar belakang tentang apa yang terjadi:

Di 1.6.6 , kami memperbaiki regresi di mana kami tidak mengkodekan tipe "gumpalan" base64 yang sebelumnya telah kami enkode. Akibatnya, Anda sekarang perlu menentukan byte biner mentah untuk parameter apa pun yang ditandai sebagai tipe "gumpalan", dan secara internal kami akan secara otomatis mengkodekan base64 untuk Anda. Ini berarti bahwa untuk enkripsi kunci round trip, Anda harus mendekode base64 terlebih dahulu:

$ 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

Dalam contoh ini, saya juga menggunakan awalan fileb:// karena ini adalah file dengan konten biner.

Saya percaya perilaku harus tetap apa adanya. Mengingat bahwa perilaku dalam edisi awal ini bergantung pada regresi di 1.6.5 yang telah diperbaiki di 1.6.6, kami benar-benar tidak dapat mengubah perilaku yang sudah ada sebelumnya, karena itu akan menjadi perubahan besar bagi pelanggan. Cuplikan contoh di atas adalah cara yang diharapkan untuk menangani input/output biner di AWS CLI, dan kecuali untuk regresi baru-baru ini, adalah cara perilaku ini selalu terjadi.

Terima kasih atas pembaruannya!

Sebenarnya, sekarang saya mendapatkan kesalahan yang mirip dengan masalah #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 Apa versi AWS CLI yang Anda gunakan? Saya baru saja mencoba lagi pada versi terbaru AWS CLI (1.6.8) dan saya tidak melihat masalah ini:

~ $ 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 berfungsi sekarang di 1.6.8. Terima kasih

@jamesls secara pribadi saya pikir ini adalah UI yang sangat buruk. Tidak dapat meneruskan ciphertext yang sama ke dalam dekripsi yang Anda dapatkan dari enkripsi? Jika Anda tidak dapat mengubahnya karena Anda tidak ingin merusak pelanggan yang sudah ada, setidaknya beri mereka pesan kesalahan yang lebih baik.

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

Bahkan tidak memberi tahu saya apa yang harus dilakukan untuk memperbaiki masalah dari jarak jauh. Anda dapat mendeteksi bahwa sandi itu mungkin Base64 dan menghasilkan kesalahan yang lebih baik dan mengarahkannya ke URL atau sesuatu.

Atau kenapa tidak memberikan tanda tambahan ke decrypt untuk mengatakan "decode ini dari base64 dulu"?

Bagi mereka yang datang ke sini nanti, untuk melakukan ini _tanpa_ menyimpan ciphertext ke file, Anda dapat melakukan:

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

Catatan: seperti yang ditunjukkan oleh @hauntingEcho di bawah, <(cmd) tidak sesuai dengan POSIX jadi jika Anda menggunakan sh , itu tidak akan berfungsi, tetapi bash dan zsh berfungsi dengan baik.

Re: komentar @thegranddesign , di OS X setidaknya saya harus menggunakan huruf kapital 'D' untuk base64 . Misalnya:

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

Decrypted: Hello world!

(Tidak yakin mengapa saya mendapatkan baris baru sebelum baris Decrypted , tetapi bukan masalah besar).

Ini berhasil untuk saya

#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

Saya memiliki masalah serupa, tetapi Node membantu:

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

catatan lain tentang solusi @thegranddesign - <(cmd) adalah bashisme, tidak sesuai dengan POSIX, jadi Anda harus menggunakan solusi lain jika bash bukan pilihan.

Ini adalah bug yang sangat bodoh yang benar-benar harus tetap terbuka sampai benar-benar diperbaiki. Ini adalah anti-pola raksasa untuk membangun alat yang melakukan operasi simetris yang menggunakan satu format untuk output dan format yang sama sekali berbeda (dan tidak kompatibel) untuk input. Alat simetris yang tidak dapat menggunakan outputnya sendiri sebagai input adalah RUSAK. Saya tidak peduli apakah itu benar-benar berfungsi sebagaimana dimaksud, itu masih rusak. Alat ini harus menghasilkan output biner mentah secara default jika bergantung pada input biner mentah, atau yang lain harus dapat menggunakan input yang disandikan base64 YANG DIHASILKAN tanpa menentukan langkah dekode base64 eksplisit atau params khusus yang tidak juga diperlukan untuk menghasilkan output itu (atau anti-param jika tidak menggunakan param yang sama persis). Sangat tidak masuk akal bahwa saya dapat menggunakan aws kms encrypt untuk menghasilkan output yang disandikan base64 dari muatan enkripsi yang disandikan base64 tanpa menentukan SALAH SATU dari pengkodean base64 tersebut, tetapi kemudian saya harus secara eksplisit mendekode base64 baik data terenkripsi DAN data yang didekripsi untuk mendapatkan kembali ke formulir yang saya berikan di tempat pertama. Fakta bahwa melakukannya juga memerlukan penggunaan params baris perintah yang bahkan tidak didokumentasikan pada tingkat sub-perintah enkripsi dan dekripsi membuatnya jauh lebih sulit untuk diketahui. Semua pengguna dijamin menghabiskan waktu berjam-jam untuk mencari cara melakukan satu hal paling jelas yang mungkin ingin dilakukan seseorang dengan klien enkripsi/dekripsi - mengenkripsi dan kemudian mendekripsi string yang ditentukan dalam param baris perintah - dan sepenuhnya karena alat memiliki mode operasi yang rusak di mana output tidak kompatibel dengan input meskipun fakta bahwa kedua sub-perintah seharusnya simetris. Menutup ini tanpa memperbaikinya menyatakan bahwa Anda sama sekali tidak peduli dengan kegunaan atau efisiensi pengembang.

jalur lain untuk menyelesaikan ini (sebagai lawan dari flag baru, seperti yang disebutkan @thegranddesign bertahun-tahun yang lalu) bisa jadi / bukan karakter base64 yang valid, dan tidak ada cara yang valid untuk menentukan data biner di json. Karena itu:

  • jika parameter ciphertext-blob valid base-64, berikan sebagai base 64
  • jika parameter ciphertext-blob berisi / , parsing sebagai jalur. fileb:// melakukan perilakunya saat ini, file:// dapat dikodekan b64.

Setuju dengan @sgendler-stem - tiket ini ditautkan di setiap proyek yang saya kerjakan yang menggunakan KMS, karena selalu menjadi masalah bagi seseorang yang mencoba bergabung.

Ini adalah bug yang sangat bodoh yang benar-benar harus tetap terbuka sampai benar-benar diperbaiki. Ini adalah anti-pola raksasa untuk membangun alat yang melakukan operasi simetris yang menggunakan satu format untuk output dan format yang sama sekali berbeda (dan tidak kompatibel) untuk input. Alat simetris yang tidak dapat menggunakan outputnya sendiri sebagai input adalah RUSAK. Saya tidak peduli apakah itu benar-benar berfungsi sebagaimana dimaksud, itu masih rusak. Alat ini harus menghasilkan output biner mentah secara default jika bergantung pada input biner mentah, atau yang lain harus dapat menggunakan input yang disandikan base64 YANG DIHASILKAN tanpa menentukan langkah dekode base64 eksplisit atau params khusus yang tidak juga diperlukan untuk menghasilkan output itu (atau anti-param jika tidak menggunakan param yang sama persis). Sangat tidak masuk akal bahwa saya dapat menggunakan aws kms encrypt untuk menghasilkan output yang disandikan base64 dari muatan enkripsi yang disandikan base64 tanpa menentukan SALAH SATU dari pengkodean base64 tersebut, tetapi kemudian saya harus secara eksplisit mendekode base64 baik data terenkripsi DAN data yang didekripsi untuk mendapatkan kembali ke formulir yang saya berikan di tempat pertama. Fakta bahwa melakukannya juga memerlukan penggunaan params baris perintah yang bahkan tidak didokumentasikan pada tingkat sub-perintah enkripsi dan dekripsi membuatnya jauh lebih sulit untuk diketahui. Semua pengguna dijamin menghabiskan waktu berjam-jam untuk mencari cara melakukan satu hal paling jelas yang mungkin ingin dilakukan seseorang dengan klien enkripsi/dekripsi - mengenkripsi dan kemudian mendekripsi string yang ditentukan dalam param baris perintah - dan sepenuhnya karena alat memiliki mode operasi yang rusak di mana output tidak kompatibel dengan input meskipun fakta bahwa kedua sub-perintah seharusnya simetris. Menutup ini tanpa memperbaikinya menyatakan bahwa Anda sama sekali tidak peduli dengan kegunaan atau efisiensi pengembang.

Saya harus sepenuhnya setuju dengan @sgendler-stem - jika kode menghasilkan output, setidaknya , dapat menganggapnya sebagai input.

Namun, ada lebih dari itu. Jika enkripsi dilakukan melalui SDK - menambahkan arn aneh di akhir file terenkripsi, CLI tidak akan dapat mendekripsinya, bahkan setelah menghapus arn non-base64 url. Ini baru saja rusak .

Setuju lagi. Ini telah membuat hal-hal yang tidak perlu membuat frustrasi.

Ini beneran tutup? Mengapa? Saya tidak percaya sudah 4 tahun sejak ini dibuka dan satu-satunya umpan balik tampaknya adalah seseorang yang mengatakan "berfungsi sebagaimana dimaksud". Tidak, tidak; @sgendler-stem tepat sasaran, ini benar-benar rusak. Berharap tim yang bertanggung jawab merasa buruk tentang diri mereka sendiri.

Hadapi pengecualian yang sama:
botocore.errorfactory.InvalidCiphertextException: Terjadi kesalahan (InvalidCiphertextException) saat memanggil operasi Dekripsi:

Digunakan:
kunci = b64decode(kunci)
respon = klien.dekripsi(
CiphertextBlob=kunci
)

Saya pikir ini tidak akan membuat frustrasi jika output dari encrypt , generate-data-key , dll tidak memanggil bidang CiphertextBlob . Ketika input ke decrypt juga disebut --ciphertext-blob , sama sekali tidak intuitif bahwa gumpalan ciphertext ini perlu dikodekan secara berbeda.

Jika bendera ke decrypt memiliki nama yang berbeda, itu akan menjadi petunjuk bahwa ia memiliki penyandian yang berbeda.

Ada proposal fitur untuk input yang disandikan base64 untuk didekripsi di sini https://github.com/aws/aws-cli/issues/2063

@ojitha

Bagaimana kms mengetahui kunci enkripsi mana yang digunakan untuk dekripsi, karena kami tidak melewatkan key-id sebagai parameter saat mendekripsi.

@ arpit728 Saya pikir CipherTextBlob yang dikembalikan khusus tentang KeyID dari CMK tertentu.

Silakan buka kembali tiket ini sampai diselesaikan!

bermain terlalu banyak jam dengan ini sampai menemukan tiket ini. apakah ada dokumentasi resmi yang menyatakan bagaimana tepatnya hal-hal harus dikodekan dan diubah antara mengenkripsi dan mendekripsi?

Hanya sedikit info latar belakang tentang apa yang terjadi:

Di 1.6.6 , kami memperbaiki regresi di mana kami tidak mengkodekan tipe "gumpalan" base64 yang sebelumnya telah kami enkode. Akibatnya, Anda sekarang perlu menentukan byte biner mentah untuk parameter apa pun yang ditandai sebagai tipe "gumpalan", dan secara internal kami akan secara otomatis mengkodekan base64 untuk Anda. Ini berarti bahwa untuk enkripsi kunci round trip, Anda harus mendekode base64 terlebih dahulu:

$ 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

Dalam contoh ini, saya juga menggunakan awalan fileb:// karena ini adalah file dengan konten biner.

contoh ini mengembalikan:

Terjadi kesalahan (InvalidCiphertextException) saat memanggil operasi Dekripsi:
Didekripsi:

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

echo "Didekripsi: $(aws kms decrypt --ciphertext-blob fileb:./encrypted-file --query Plaintext --output text | base64 --decode)"
`
Mencoba dengan ubuntu. Jika ada yang tahu dokumentasi atau contoh yang jelas (tautan ke situs atau sesuatu) saya akan sangat berterima kasih!

EDIT: buat enkripsi dan dekripsi berfungsi menggunakan tip dari artikel ini: https://dev.to/matchilling/pragmatically-storing-security-sensitive-data-using-aws-kms-5e5b

FYI, tautan di atas tidak berfungsi, tetapi artikelnya tampaknya cukup berguna dan tersedia di sini .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat