JWT kodunu çözebilirseniz, nasıl güvende olurlar?


302

Bir JWT alırsam ve yükü çözebilirsem, bu nasıl güvenli? Jetonu başlıktan alıp, koddaki kullanıcı bilgilerini deşifre edip değiştirip aynı doğru kodlanmış sır ile geri gönderemedim mi?

Güvenli olmaları gerektiğini biliyorum, ama sadece teknolojileri anlamak istiyorum. Neyi kaçırıyorum?


2
md5('original messaged' + secret) != md5('changed message' + secret)böylece birisi mesajı değiştirirse onu tespit edebilirsiniz
Pithikos

ideal bir durum için doğru olsa da, md5'in çarpışmaları vardır. @Pithikos
Yash Kumar Verma

@YashKumarVerma evet, herkes md5'i bildiği için sadece bunun özünü göstermek için.
Pithikos

1
@ user1955934 base64 kodlanmış olan değil şifrelenmiş. Herhangi bir base64 kod çözücü ile deşifre edebilirsiniz.
Pithikos

1
böylece müşteri hem karma hem de jwt jetonu göndermesi gerekecek? ve daha sonra sunucu tarafında gizli kullanarak jwt belirteç karma ve karma ile karşılaştırmak için çalışacağız?
user1955934

Yanıtlar:


387

JWT'ler imzalı, şifreli veya her ikisi birden olabilir. Bir işaret imzalanmış ancak şifrelenmemişse, herkes içeriğini okuyabilir, ancak özel anahtarı bilmediğinizde değiştiremezsiniz. Aksi takdirde, alıcı imzanın artık eşleşmediğini fark edecektir.

Yorumunuza cevap verin: Yorumunuzu doğru şekilde anladığımdan emin değilim. Sadece emin olmak için: dijital imzaları biliyor ve anlıyor musunuz? Kısaca bir varyantı açıklayacağım (HMAC, simetrik, ancak diğerleri var).

Diyelim ki Alice Bob'a bir JWT göndermek istiyor. İkisi de paylaşılan bir sır biliyorlar. Mallory bu sırrı bilmiyor, ama JWT'ye müdahale etmek ve değiştirmek istiyor. Bunu önlemek için Alice Hash(payload + secret)bunu imza olarak hesaplar ve ekler.

İletiyi alırken, Bob Hash(payload + secret)imzanın eşleşip eşleşmediğini de hesaplayabilir . Ancak, Mallory içerikte bir şey değiştirirse, eşleşen imzayı (ki Hash(newContent + secret)) hesaplayamaz . Sırrı bilmiyor ve onu bulmanın bir yolu yok. Bu, bir şeyi değiştirirse, imza artık eşleşmeyeceği ve Bob'un artık JWT'yi kabul etmeyeceği anlamına gelir.

Diyelim ki başka bir kişiye mesajı gönderiyorum {"id":1}ve imzalayacağım Hash(content + secret). (+ burada sadece birleştirme). Ben SHA256 Hash fonksiyonu kullanıyorum ve almak imzadır: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Şimdi sıra sizde: Mallory rolünü oynayın ve mesajı imzalamaya çalışın {"id":2}. Yapamazsın çünkü hangi sırrı kullandığımı bilmiyorsun. Alıcının sırrını bildiğini varsayarsak, herhangi bir mesajın imzasını hesaplayabilir ve doğru olup olmadığını kontrol edebilir.


8
Yük değiştiğinde imza değişiyor mu? Simgenin [header] biçiminde olduğu izlenimindeydim. [Faydalı]. [İmza] İmza yükü ve sır kombinasyonu ile hesaplanıyor mu? Eğer durum buysa, farklı kimliğe sahip bir yük bu sır için aynı olmaz mıydı? Veriler {id: 1} olsaydı ve belirtecin imza kısmını sır ile hesaplamak için kullanılırsa, {id: 2} kullanıcı 2 için geçerli olacağı anlamına gelmez ve böylece kullanıcı 1 değişebilir id 2 ve jeton aynı olurdu?
PixMach

7
Size işleri daha net hale getirmek için bir örnek verdim, ancak size tüm dijital imza ve HMAC kavramlarını açıklamayacağım. Lütfen bu şeyleri okuyun, açıklayan çok fazla malzeme var.
Misch

11
Oh şimdi anladım. Yükü değiştirdiğinizde gizli karmanın doğru olmayacağı fikrini neden kaçırdığımı bilmiyorum çünkü gizli karmanın yeniden hesaplanması gerekiyor. Nedense hala bağımsız olduğunu düşünüyordum. Bu son parça gerçekten benim için eve açıldı. Beni içinden geçtiğiniz için teşekkürler.
PixMach

30
Ben ilgili bir sorum var. Birinin Alice'i kopyalanan JWT ile taklit etmesini engelleyen nedir?
Morrowless

25
Birisinin JWT'si varsa Alice'i taklit edebilir. Bu yüzden nasıl sakladığınıza ve gönderdiğinize dikkat etmelisiniz. Ayrıca, yükte bunun için bir sona erme tarihi ayarlamanız gerekir. Bu şekilde biri JWT'yi çalarsa, bunu kullanmak için sınırlı bir zaman dilimi vardır. Stormpath.com/blog/…
Geraint Anderson'a

134

Sen gidebilirsin jwt.io, senin jeton yapıştırın ve içeriğini okuyun. Bu başlangıçta birçok insan için sarsıcı.

Kısa cevap, JWT'nin şifreleme ile ilgilenmemesi. Doğrulamayı önemsiyor. Yani her zaman "Bu tokenin içeriği manipüle edildi mi?" Bu, sunucu jetonu tanıyacağı ve dikkate almayacağı için JWT jetonunun kullanıcı tarafından değiştirilmesinin boş olduğu anlamına gelir. Sunucu, istemciye bir belirteç verirken yüke dayalı bir imza ekler. Daha sonra yük ve eşleşen imzayı doğrular.

Mantıksal soru, kendisini şifrelenmiş içeriklerle ilişkilendirmemenin motivasyonu nedir?

  1. Bunun en basit nedeni, bunun çoğunlukla çözülmüş bir sorun olduğunu varsaymasıdır. Örneğin, web tarayıcısı gibi bir istemciyle uğraşıyorsanız, JWT belirteçlerini secure(HTTP aracılığıyla aktarılmaz, yalnızca HTTPS aracılığıyla httpOnlygönderilir ) ve (Javascript tarafından okunamaz ) olan bir çerezde saklayabilirsiniz. şifreli bir kanal (HTTPS). Sunucu ve istemci arasında güvenli bir kanalınız olduğunu öğrendikten sonra JWT'yi veya başka herhangi bir şeyi güvenli bir şekilde değiştirebilirsiniz.

  2. Bu her şeyi basitleştirir. Basit bir uygulama benimsemeyi kolaylaştırır, ancak her katmanın en iyi yapısını yapmasına izin verir (HTTPS'nin şifrelemeyi işlemesine izin ver).

  3. JWT, hassas verileri depolamak anlamına gelmez. Sunucu JWT jetonunu aldığında ve doğruladığında, o kullanıcı için ek bilgiler (izinler, posta adresi vb.) İçin kendi veritabanında kullanıcı kimliğini aramak ücretsizdir. Bu, JWT'nin boyutunu küçük tutar ve herkesin hassas verileri JWT'de tutmamayı bildiği için yanlışlıkla bilgi sızıntısını önler.

Çerezlerin nasıl çalıştığından çok farklı değil. Çerezler genellikle şifrelenmemiş faydalı yükler içerir. HTTPS kullanıyorsanız, o zaman her şey iyidir. Eğer değilseniz, hassas çerezleri kendileri şifrelemeniz önerilir. Bunu yapmamak ortadaki adam saldırısının mümkün olacağı anlamına gelecektir - bir proxy sunucusu veya İSS çerezleri okur ve daha sonra sizmiş gibi davranarak tekrar oynatır. Benzer nedenlerle, JWT her zaman HTTPS gibi güvenli bir katman üzerinden değiştirilmelidir.


4
Dikkat et! JWT her zaman HTTPS gibi güvenli bir katman üzerinden değiştirilmelidir
codemirror

Fakat JWT sadece HTTPS üzerinden güvenliyse, neden sadece yükü göndermiyorsunuz? POST -> kullanıcı adı, şifre. Hala şifreli değil mi?
GeekPeek

@GeekPeek JWT temelleri üzerinde okumak gerekir ama sizin gibi Oturum Auth genellikle ihtiyacınız olan tek şey. JWT başka avantajlar da sunuyor ancak bazı ödünleşmeler yapıyor webskeleton.com/webdev/2019/10/22/…
aleemb

17

Bir json web jetonundaki (JWT) içerikler doğal olarak güvenli değildir, ancak jeton orijinalliğini doğrulamak için yerleşik bir özellik vardır. JWT, noktalarla ayrılmış üç karma değerdir. Üçüncüsü imza. Ortak / özel anahtar sisteminde, yayıncı belirteç imzasını yalnızca ilgili ortak anahtarla doğrulanabilen özel bir anahtarla imzalar.

İhraççı ve doğrulayıcı arasındaki farkı anlamak önemlidir. Jetonun alıcısı, doğrulamaktan sorumludur.

Bir web uygulamasında JWT'yi güvenli bir şekilde kullanmanın iki kritik adımı vardır: 1) bunları şifreli bir kanal üzerinden gönderin ve 2) imzayı aldıktan hemen sonra doğrulayın. Ortak anahtar şifrelemesinin asimetrik doğası JWT imza doğrulamasını mümkün kılar. Ortak anahtar, eşleşen bir özel anahtarla bir JWT'nin imzalandığını doğrular. Başka hiçbir tuş kombinasyonu bu doğrulamayı yapamaz, böylece kimliğe bürünme girişimlerini önler. Bu iki adımı izleyin ve bir JWT'nin gerçekliğini matematiksel olarak kesin olarak garanti edebiliriz.

Daha fazla okuma: Ortak anahtar bir imzayı nasıl doğrular?


2

En başından tartışalım:

JWT, Json Web Jetonlarını genişleten çok modern, basit ve güvenli bir yaklaşımdır. Json Web Jetonları kimlik doğrulama için durumsuz bir çözümdür. Bu nedenle, elbette dinlendirici API'ler için mükemmel olan herhangi bir oturum durumunu sunucuda depolamaya gerek yoktur. Dinlendirici API'ler her zaman vatansız olmalıdır ve JWT'lerle kimlik doğrulamanın en yaygın kullanılan alternatifi, oturumları kullanarak kullanıcının oturum açma durumunu sunucuda depolamaktır. Ancak elbette, huzurlu API'lerin vatansız olması gerektiğini söyleyen ilkeyi takip etmiyor ve bu yüzden JWT gibi çözümler popüler ve etkili oldu.

Şimdi, kimlik doğrulamanın Json Web Tokens ile gerçekten nasıl çalıştığını öğrenelim. Veritabanımızda zaten kayıtlı bir kullanıcımız olduğu varsayılarak. Kullanıcının istemcisi, kullanıcı adı ve parola ile bir gönderi isteği yaparak başlar, uygulama daha sonra kullanıcının var olup olmadığını kontrol eder ve parola doğru ise, uygulama yalnızca o kullanıcı için benzersiz bir Json Web Jetonu oluşturur.

Belirteç bir kullanılarak oluşturulan gizli dize olan bir sunucuda depolanan . Daha sonra, sunucu bu JWT'yi istemciye geri gönderir ve bu da bir çerezde veya yerel depoda saklar. resim açıklamasını buraya girin

Bunun gibi, kullanıcı kimliği doğrulanır ve temel olarak sunucuda herhangi bir durum bırakmadan uygulamamıza giriş yapar.

Yani sunucu aslında hangi kullanıcının gerçekten giriş yaptığını bilmiyor, ancak elbette kullanıcı, uygulamanın korumalı bölümlerine erişmek için biraz pasaport gibi geçerli bir Json Web Jetonuna sahip olduğu için giriş yaptığını biliyor.

Yine, sadece fikri anladığınızdan emin olmak için. Bir kullanıcı, sunucuda herhangi bir yere kaydedilmemiş olan benzersiz geçerli Json Web Jetonunu geri alır almaz oturum açar. Dolayısıyla bu süreç tamamen vatansızdır.

Ardından, her kullanıcı, kullanıcı profili verileri gibi korunan bir rotaya her erişmek istediğinde. Json Web Jetonunu bir istekle birlikte gönderir, bu yüzden bu rotaya erişmek için pasaportunu göstermek gibi.

İstek sunucuya çarptığında, uygulamamız Json Web Token'ın gerçekten geçerli olup olmadığını doğrular ve kullanıcı gerçekten söylediği kişi ise, o zaman istenen veriler istemciye gönderilir ve değilse, o zaman kullanıcıya bu kaynağa erişmesine izin verilmediğini söyleyen bir hata olabilir. resim açıklamasını buraya girin

Tüm bu iletişim https üzerinden gerçekleşmelidir, Herkesin parolalara veya Json Web Jetonlarına erişmesini önlemek için şifreli Http'yi güvenli hale getirin. Ancak o zaman gerçekten güvenli bir sistemimiz var.

resim açıklamasını buraya girin

Yani bir Json Web Jetonu, jwt.ioSo'daki JWT hata ayıklayıcısından alınan bu ekran görüntüsünün sol kısmına benziyor, aslında üç bölümden oluşan bir kodlama dizesi. Üstbilgi, yük ve imza Şimdi üstbilgi, yalnızca belirtecin kendisi hakkında bazı meta verilerdir ve yük, belirtecin içine kodlayabildiğimiz, gerçekten istediğimiz verilerdir. Yani burada daha fazla veri kodlamak istediğimizde JWT daha büyük olur. Her neyse, bu iki bölüm yalnızca şifrelenecek ancak şifrelenmeyecek düz metindir.

Böylece kimse bunları çözebilir ve okuyabilir , burada hassas verileri saklayamayız. Ama bu hiç de sorun değil çünkü üçüncü bölümde, yani imzada, işlerin gerçekten ilginçleştiği yer. İmza, üstbilgi, faydalı yük ve sunucuya kaydedilen sır kullanılarak oluşturulur.

Ve tüm bu sürece Json Web Jetonunu imzalama denir . İmza algoritması, benzersiz bir imza oluşturmak için başlığı, yükü ve sırrı alır. Yani sadece bu veri artı sır bu imzayı yaratabilir, tamam mı? Daha sonra üstbilgi ve yük ile birlikte bu imza, daha sonra istemciye gönderilen JWT'yi oluşturur. resim açıklamasını buraya girin

Sunucu korumalı bir rotaya erişim izni vermek için bir JWT aldığında, kullanıcının gerçekte kim olduğunu iddia edip etmediğini belirlemek için bunu doğrulaması gerekir. Başka bir deyişle, kimsenin jetonun başlığını ve yük verilerini değiştirip değiştirmediğini doğrular. Bu nedenle, bu doğrulama adımı, hiçbir üçüncü tarafın Json Web Token'ın üstbilgisini veya yükünü gerçekten değiştirip değiştirmediğini kontrol edecektir.

Peki, bu doğrulama aslında nasıl çalışıyor? Aslında oldukça basittir. JWT alındıktan sonra, doğrulama üstbilgisini ve yükünü alır ve hala sunucuda kayıtlı olan sır ile birlikte temel olarak bir test imzası oluşturur.

Ancak, JWT ilk oluşturulduğunda oluşturulan orijinal imza hala belirteçte, değil mi? Ve bu doğrulamanın anahtarı bu. Çünkü şimdi tek yapmamız gereken test imzasını orijinal imzayla karşılaştırmak. Test imzası orijinal imzayla aynıysa, yükün ve başlığın değiştirilmediği anlamına gelir. resim açıklamasını buraya girin

Çünkü değiştirilmiş olsaydı, test imzasının farklı olması gerekirdi. Bu nedenle, verilerde değişiklik olmadığı bu durumda, kullanıcının kimliğini doğrulayabiliriz. Ve elbette, iki imza gerçekten farklıysa, o zaman birisinin veriyi kurcaladığı anlamına gelir. Genellikle yükü değiştirmeye çalışarak. Ancak, yükü manipüle eden üçüncü tarafın elbette sırra erişimi yoktur, bu nedenle JWT'yi imzalayamazlar. Böylece orijinal imza asla manipüle edilen verilere karşılık gelmez. Bu nedenle, doğrulama bu durumda her zaman başarısız olacaktır. Ve tüm bu sistemi çalıştırmanın anahtarı budur. JWT'yi bu kadar basit, ama aynı zamanda son derece güçlü yapan sihir.


1

Yalnızca JWT'nin sunucunuzdaki privateKey şifreli JWT'nin şifresini çözecektir. PrivateKey'i bilenler, şifrelenmiş JWT'nin şifresini çözebilir.

PrivateKey'i sunucunuzda güvenli bir yerde saklayın ve asla privateKey'e söylemeyin.


1
JWT'ler her zaman şifrelenmez. İmzalanabilir, şifrelenebilir, imzalanabilir, şifrelenebilir veya şifrelenip imzalanabilir.
csauve

0

Benim gibi pahalı veritabanı sorgularını karşılayamayan insanlar için, hassas verileri saklamanın bir seçeneği (Kullanıcı ayrıcalıkları vb.) JWT'yi oluştururken bu verileri şifreleyebilir ve JWT jetonuna ekleyebilirsiniz. (Şifreleme anahtarını arka uçta tutun)

Hassas bilgileri okumak istediğinizde JWT jetonunu arka uca gönderebilir ve şifresini çözebilir ve bilgileri geri alabilirsiniz. Bu şekilde, DB aramaları yapmanız veya hassas bilgilerin JWT jetonu aracılığıyla ön uçta çıplak olması gerekmez


-1

Jwt.io şifresini çözmek için mevcut olmayan özel algoritmalar kullanarak JWE içine bakmak öneririz

Referans bağlantısı: 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
  });
});

Bu cevap çok geç olabilir ya da zaten yolu bulmuş olabilirsiniz, ancak yine de bunun sizin ve başkaları için de yararlı olacağını hissettim.

Oluşturduğum basit bir örnek: https://github.com/hansiemithun/jwe-example

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.