Jika Anda dapat mendekode JWT, bagaimana mereka aman?

302

Jika saya mendapatkan JWT dan saya dapat memecahkan kode payload, bagaimana itu aman? Tidak bisakah saya mengambil token dari header, men-decode dan mengubah informasi pengguna di payload, dan mengirimkannya kembali dengan rahasia yang disandikan dengan benar yang sama?

Saya tahu mereka harus aman, tetapi saya hanya ingin memahami teknologinya. Apa yang saya lewatkan?

PixMach
sumber
2
md5('original messaged' + secret) != md5('changed message' + secret)jadi jika seseorang mengubah pesan Anda dapat mendeteksinya
Pithikos
berlaku untuk kasus yang ideal, namun, MD5 memiliki tabrakan. @Pithikos
Yash Kumar Verma
@YashKumarVerma ya, itu hanya untuk menunjukkan intinya karena semua orang tahu md5.
Pithikos
1
@ user1955934 itu dikodekan base64, TIDAK dienkripsi. Anda bisa mendekodekannya dengan decoder base64 apa pun.
Pithikos
1
jadi klien perlu mengirim hash dan token jwt? dan kemudian di sisi server mereka akan mencoba untuk hash token jwt menggunakan rahasia dan membandingkan dengan hash?
user1955934

Jawaban:

387

JWT dapat ditandatangani, dienkripsi atau keduanya. Jika token ditandatangani, tetapi tidak dienkripsi, semua orang bisa membaca isinya, tetapi ketika Anda tidak tahu kunci privat, Anda tidak bisa mengubahnya. Kalau tidak, penerima akan melihat bahwa tanda tangan tidak akan cocok lagi.

Jawab komentar Anda: Saya tidak yakin apakah saya memahami komentar Anda dengan benar. Hanya untuk memastikan: apakah Anda tahu dan mengerti tanda tangan digital? Saya hanya akan menjelaskan secara singkat satu varian (HMAC, yang simetris, tetapi ada banyak lainnya).

Mari kita asumsikan Alice ingin mengirim JWT ke Bob. Mereka berdua tahu rahasia bersama. Mallory tidak tahu rahasia itu, tetapi ingin ikut campur dan mengubah JWT. Untuk mencegahnya, Alice menghitung Hash(payload + secret)dan menambahkan ini sebagai tanda tangan.

Saat menerima pesan, Bob juga dapat menghitung Hash(payload + secret)untuk memeriksa apakah tanda tangan cocok. Namun jika, Mallory mengubah sesuatu dalam konten, dia tidak dapat menghitung tanda tangan yang cocok (yang akan menjadi Hash(newContent + secret)). Dia tidak tahu rahasianya dan tidak memiliki cara untuk mengetahuinya. Ini berarti jika dia mengubah sesuatu, tanda tangannya tidak akan cocok lagi, dan Bob tidak akan menerima JWT lagi.

Anggap saja, saya mengirim pesan kepada orang lain {"id":1}dan menandatanganinya Hash(content + secret). (+ hanya penggabungan di sini). Saya menggunakan fungsi SHA256 Hash, dan tanda tangan saya dapatkan adalah: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Sekarang giliran Anda: mainkan peran Mallory dan coba tandatangani pesannya {"id":2}. Anda tidak bisa karena Anda tidak tahu rahasia mana yang saya gunakan. Jika saya mengira bahwa penerima tahu rahasianya, dia BISA menghitung tanda tangan pesan apa pun dan memeriksa apakah itu benar.

Misch
sumber
8
Jadi tanda tangan diubah ketika payload diubah? Saya mendapat kesan bahwa tokennya dalam format [header]. [Payload]. [Signature] apakah tanda tangan dihitung dengan kombinasi payload dan secret? Jika itu masalahnya, bukankah muatan dengan id berbeda akan sama untuk rahasia itu? Seperti jika data adalah {id: 1} dan yang digunakan untuk menghitung bagian tanda tangan dari token dengan rahasia, bukankah itu berarti bahwa {id: 2} akan valid untuk pengguna 2, sehingga pengguna 1 dapat mengubah id ke 2 dan token akan sama?
PixMach
7
Saya memang memberi Anda contoh untuk membuat segalanya lebih jelas, tapi saya tidak akan menjelaskan kepada Anda seluruh konsep tanda tangan digital dan HMAC untuk Anda. Silakan baca tentang hal-hal itu, ada banyak bahan yang menjelaskannya.
Misch
11
Oh saya mengerti sekarang. Saya tidak tahu mengapa saya kehilangan ide bahwa hash rahasia tidak akan benar ketika Anda mengubah muatan karena hash rahasia harus dihitung ulang. Untuk beberapa alasan saya masih berpikir bahwa itu independen. Bagian terakhir itu benar-benar mengebornya untuk saya. Terima kasih telah menuntun saya melewatinya.
PixMach
30
Saya punya pertanyaan terkait. Apa yang mencegah seseorang menyamar sebagai Alice dengan JWT yang disalin?
Morrowless
25
Jika seseorang memiliki JWT, mereka dapat menyamar sebagai Alice. Jadi, Anda perlu berhati-hati bagaimana Anda menyimpan dan mengirimnya. Anda juga harus menetapkan kedaluwarsa untuk itu di payload. Dengan begitu jika seseorang mencuri JWT, mereka memiliki jangka waktu terbatas untuk menggunakannya. Lihat stormpath.com/blog/…
Geraint Anderson
134

Anda dapat pergi ke jwt.io, tempel token Anda dan baca isinya. Ini menggelegar bagi banyak orang pada awalnya.

Jawaban singkatnya adalah JWT tidak mementingkan enkripsi. Itu peduli tentang validasi. Artinya, selalu bisa mendapatkan jawaban untuk "Sudahkah konten token ini dimanipulasi"? Ini berarti manipulasi pengguna token JWT sia-sia karena server akan mengetahui dan mengabaikan token. Server menambahkan tanda tangan berdasarkan muatan ketika mengeluarkan token kepada klien. Kemudian itu memverifikasi muatan dan tanda tangan yang cocok.

Pertanyaan logisnya adalah apa motivasi untuk tidak memedulikan dirinya dengan konten terenkripsi?

  1. Alasan paling sederhana adalah karena menganggap ini adalah masalah yang diselesaikan untuk sebagian besar. Jika berhadapan dengan klien seperti browser web misalnya, Anda dapat menyimpan token JWT dalam cookie yang secure(tidak dikirim melalui HTTP, hanya melalui HTTPS) dan httpOnly(tidak dapat dibaca oleh Javascript) dan berbicara ke server melalui saluran terenkripsi (HTTPS). Setelah Anda tahu Anda memiliki saluran aman antara server dan klien, Anda dapat dengan aman bertukar JWT atau apa pun yang Anda inginkan.

  2. Ini membuat semuanya tetap sederhana. Implementasi yang sederhana membuat adopsi lebih mudah tetapi juga memungkinkan setiap lapisan melakukan yang terbaik (biarkan HTTPS menangani enkripsi).

  3. JWT tidak dimaksudkan untuk menyimpan data sensitif. Setelah server menerima token JWT dan memvalidasinya, bebas untuk mencari ID pengguna di basis datanya sendiri untuk informasi tambahan untuk pengguna tersebut (seperti izin, alamat pos, dll). Ini menjaga ukuran JWT kecil dan menghindari kebocoran informasi yang tidak disengaja karena semua orang tahu untuk tidak menyimpan data sensitif di JWT.

Itu tidak terlalu berbeda dengan cara kerja cookie itu sendiri. Cookie sering mengandung muatan tidak terenkripsi. Jika Anda menggunakan HTTPS maka semuanya baik-baik saja. Jika tidak, disarankan untuk mengenkripsi cookie sensitif sendiri. Tidak melakukan hal itu berarti bahwa serangan man-in-the-middle dimungkinkan - server proxy atau ISP membaca cookie dan kemudian mengulanginya nanti dengan berpura-pura menjadi Anda. Untuk alasan yang sama, JWT harus selalu ditukar melalui lapisan aman seperti HTTPS.

aleemb
sumber
4
Pikirkan itu! JWT harus selalu dipertukarkan melalui lapisan aman seperti HTTPS
codemirror
Tetapi jika JWT hanya aman melalui HTTPS, mengapa tidak mengirim payload saja? POST -> nama pengguna, kata sandi. Itu masih dienkripsi kan?
GeekPeek
@GeekPeek untuk itu Anda harus membaca tentang dasar-dasar JWT tetapi Sesi Auth seperti yang Anda sebutkan seringkali adalah semua yang Anda butuhkan. JWT menawarkan beberapa manfaat lain tetapi membuat beberapa pengorbanan webskeleton.com/webdev/2019/10/22/…
aleemb
17

Konten dalam json web token (JWT) tidak aman secara inheren, tetapi ada fitur bawaan untuk memverifikasi keaslian token. JWT adalah tiga hash yang dipisahkan oleh titik. Yang ketiga adalah tanda tangan. Dalam sistem kunci publik / pribadi, penerbit menandatangani tanda tangan token dengan kunci pribadi yang hanya dapat diverifikasi oleh kunci publik yang sesuai.

Penting untuk memahami perbedaan antara penerbit dan pemverifikasi. Penerima token bertanggung jawab untuk memverifikasinya.

Ada dua langkah penting dalam menggunakan JWT dengan aman di aplikasi web: 1) mengirimkannya melalui saluran terenkripsi, dan 2) memverifikasi tanda tangan segera setelah menerimanya. Sifat asimetris dari kriptografi kunci publik memungkinkan verifikasi tanda tangan JWT. Kunci publik memverifikasi JWT ditandatangani oleh kunci pribadi yang cocok. Tidak ada kombinasi kunci lain yang dapat melakukan verifikasi ini, sehingga mencegah upaya peniruan identitas. Ikuti dua langkah ini dan kami dapat menjamin dengan kepastian matematis keaslian JWT.

Lebih banyak membaca: Bagaimana kunci publik memverifikasi tanda tangan?

Klik ini
sumber
2

Mari kita lupakan sejak awal:

JWT adalah pendekatan yang sangat modern, sederhana dan aman yang meluas untuk Json Web Tokens. Json Web Tokens adalah solusi tanpa kewarganegaraan untuk otentikasi. Jadi tidak perlu menyimpan status sesi apa pun di server, yang tentu saja sangat cocok untuk API yang tenang. API yang tenang harus selalu tanpa kewarganegaraan, dan alternatif yang paling banyak digunakan untuk otentikasi dengan JWT adalah dengan hanya menyimpan status masuk pengguna di server menggunakan sesi. Tapi tentu saja tidak mengikuti prinsip yang mengatakan bahwa API yang tenang harus tidak bernegara dan itu sebabnya solusi seperti JWT menjadi populer dan efektif.

Jadi sekarang mari kita tahu bagaimana sebenarnya otentikasi bekerja dengan Token Web Json. Dengan asumsi kita sudah memiliki pengguna terdaftar di database kami. Jadi klien pengguna mulai dengan membuat permintaan posting dengan nama pengguna dan kata sandi, aplikasi kemudian memeriksa apakah pengguna ada dan jika kata sandi itu benar, maka aplikasi akan menghasilkan Json Web Token unik hanya untuk pengguna itu.

Token dibuat menggunakan string rahasia yang disimpan di server . Selanjutnya, server kemudian mengirimkan JWT itu kembali ke klien yang akan menyimpannya di cookie atau di penyimpanan lokal. masukkan deskripsi gambar di sini

Sama seperti ini, pengguna diautentikasi dan pada dasarnya masuk ke aplikasi kami tanpa meninggalkan keadaan apa pun di server.

Jadi server sebenarnya tidak tahu pengguna mana yang benar-benar masuk, tetapi tentu saja, pengguna tahu bahwa dia masuk karena dia memiliki Json Web Token yang valid yang agak seperti paspor untuk mengakses bagian aplikasi yang dilindungi.

Jadi sekali lagi, hanya untuk memastikan Anda mendapat ide. Seorang pengguna login segera setelah ia mendapatkan Json Web Token unik dan valid yang tidak disimpan di mana pun di server. Dan karenanya proses ini sepenuhnya tanpa kewarganegaraan.

Lalu, setiap kali pengguna ingin mengakses rute yang dilindungi seperti data profil penggunanya, misalnya. Dia mengirim Json Web Token bersama dengan permintaannya, jadi itu seperti menunjukkan paspornya untuk mendapatkan akses ke rute itu.

Setelah permintaan mengenai server, aplikasi kami kemudian akan memverifikasi apakah Json Web Token benar-benar valid dan jika pengguna benar-benar seperti yang dikatakannya, maka data yang diminta akan dikirim ke klien dan jika tidak, maka akan ada menjadi kesalahan saat memberi tahu pengguna bahwa ia tidak diizinkan mengakses sumber daya itu. masukkan deskripsi gambar di sini

Semua komunikasi ini harus terjadi melalui https, Jadi amankan Http terenkripsi untuk mencegah siapa pun bisa mendapatkan akses ke kata sandi atau Token Web Json. Hanya dengan begitu kita memiliki sistem yang sangat aman.

masukkan deskripsi gambar di sini

Jadi Json Web Token tampak seperti bagian kiri dari tangkapan layar ini yang diambil dari JWT debugger di jwt.ioSo pada dasarnya, ini adalah string penyandian yang terdiri dari tiga bagian. Header, payload dan tanda tangan Sekarang header hanyalah beberapa metadata tentang token itu sendiri dan payload adalah data yang dapat kita enkode ke dalam token, data apa pun yang kita inginkan. Jadi semakin banyak data yang ingin kita enkode di sini, semakin besar JWT. Bagaimanapun, kedua bagian ini hanyalah teks biasa yang akan disandikan, tetapi tidak dienkripsi.

Jadi siapa pun akan dapat men-decode mereka dan membacanya , kami tidak dapat menyimpan data sensitif apa pun di sini. Tapi itu bukan masalah sama sekali karena di bagian ketiga, jadi di tanda tangan, adalah hal-hal yang benar-benar menarik. Tanda tangan dibuat menggunakan header, payload, dan rahasia yang disimpan di server.

Dan seluruh proses ini kemudian disebut menandatangani Json Web Token . Algoritma penandatanganan mengambil header, payload, dan rahasia untuk membuat tanda tangan yang unik. Jadi hanya data ini ditambah rahasia yang dapat membuat tanda tangan ini, oke? Kemudian bersama dengan tajuk dan payload, tanda tangan ini membentuk JWT, yang kemudian dikirim ke klien. masukkan deskripsi gambar di sini

Setelah server menerima JWT untuk memberikan akses ke rute yang dilindungi, server perlu memverifikasinya untuk menentukan apakah pengguna benar-benar seperti yang ia klaim. Dengan kata lain, itu akan memverifikasi jika tidak ada yang mengubah header dan data payload token. Jadi sekali lagi, langkah verifikasi ini akan memeriksa apakah tidak ada pihak ketiga yang benar-benar mengubah header atau payload Json Web Token.

Jadi, bagaimana verifikasi ini bekerja? Yah, sebenarnya cukup mudah. Setelah JWT diterima, verifikasi akan mengambil tajuk dan muatannya, dan bersama dengan rahasia yang masih tersimpan di server, pada dasarnya membuat tanda tangan pengujian.

Tetapi tanda tangan asli yang dihasilkan ketika JWT pertama kali dibuat masih dalam token, kan? Dan itulah kunci verifikasi ini. Karena sekarang yang harus kita lakukan adalah membandingkan tanda tangan tes dengan tanda tangan asli. Dan jika tanda tangan pengujian sama dengan tanda tangan asli, maka itu berarti payload dan header belum dimodifikasi. masukkan deskripsi gambar di sini

Karena jika mereka telah dimodifikasi, maka tanda tangan tes harus berbeda. Karenanya dalam kasus ini di mana tidak ada perubahan data, kami dapat mengotentikasi pengguna. Dan tentu saja, jika kedua tanda tangan itu sebenarnya berbeda, yah, itu berarti seseorang merusak data. Biasanya dengan mencoba mengubah payload. Tetapi pihak ketiga yang memanipulasi payload tentu saja tidak memiliki akses ke rahasia, sehingga mereka tidak dapat menandatangani JWT. Jadi tanda tangan asli tidak akan pernah sesuai dengan data yang dimanipulasi. Dan karenanya, verifikasi akan selalu gagal dalam kasus ini. Dan itulah kunci untuk membuat seluruh sistem ini bekerja. Ini keajaiban yang membuat JWT sangat sederhana, tetapi juga sangat kuat.

Tuan
sumber
1

Hanya privateTey JWT, yang ada di server Anda yang akan mendekripsi JWT terenkripsi. Mereka yang mengetahui privateKey akan dapat mendekripsi JWT terenkripsi.

Sembunyikan privateKey di lokasi aman di server Anda dan jangan pernah memberi tahu siapa pun privateKey.

sdfdsf sdf
sumber
1
JWT tidak selalu terenkripsi. Mereka dapat ditandatangani, dienkripsi, ditandatangani kemudian dienkripsi, atau dienkripsi kemudian ditandatangani.
csauve
0

Untuk orang-orang yang tidak mampu membayar permintaan basis data mahal seperti saya, satu opsi untuk menyimpan data sensitif (User priveledges dll) adalah, ketika menghasilkan JWT Anda dapat mengenkripsi data ini dan melampirkannya ke token JWT. (Simpan kunci enkripsi di backend)

Ketika Anda ingin membaca informasi sensitif Anda dapat mengirim token JWT ke backend dan mendekripsi dan mendapatkan informasi kembali. Dengan cara ini, Anda tidak perlu melakukan pencarian DB atau memiliki informasi sensitif telanjang di frontend melalui token JWT

Nirojan Selvanathan
sumber
-1

Saya akan menyarankan untuk melihat ke dalam JWE menggunakan algoritma khusus yang tidak ada di jwt.io untuk mendekripsi

Tautan referensi: https://www.npmjs.com/package/node-webtokens

jwt.generate('PBES2-HS512+A256KW', 'A256GCM', payload, pwd, (error, token) => {
  jwt.parse(token).verify(pwd, (error, parsedToken) => {
    // other statements
  });
});

Jawaban ini mungkin sudah terlambat atau Anda mungkin sudah menemukan jalannya, tetapi tetap saja, saya merasa itu akan membantu Anda dan orang lain juga.

Contoh sederhana yang saya buat: https://github.com/hansiemithun/jwe-example

Mithun Shreevatsa
sumber