Web tabanlı uygulamalarda veri iletimi yapılırken, uygulamalar arası iletişimi güvenli şekilde kurabilmek ve isteklere dışarıdan müdahale edilmediğinden emin olmak oldukça önemlidir. Bizler de Ödeme Sistemleri dünyasında ödeme akışının uçtan uca güvenli bir şekilde tamamlanmasını sağlamak, servisler arasında aktarılan mesajlarda herhangi bir manipülasyon yapılmadığını teyit etmek amacıyla farklı yöntemlere başvuruyoruz. Bugün bu yöntemlerden biri olan ve 3D Secure 2.0 altyapısında da kullanıyor olduğumuz JSON Web Signature (JWS) standardından bahsediyor olacağım.
JWS, Json formatındaki verileri dijital olarak imzalamak ve doğrulamak için kullanılan bir standarttır. Haberleşen iki veya daha fazla sistem arasında kimlik doğrulama, veri bütünlüğünü sağlama, güvenli veri transferini sağlama gibi noktalarda kullanılmaktadır. Teknik olarak JWS, birkaç parçadan oluşan ve base64 URL kodlamasını kullanan bir istek paketleme formatıdır. Şimdi bu paketin yapısını inceleyelim.
JWS’nin Yapısı:
JWS temel olarak 3 parçadan oluşur. Her bir parça “.” İle birbirinden ayrılır. Örnek olarak aşağıdaki string ifadeye baktığımızda farklı renklerle belirtilen parçaların decoded hallerini alttaki kutucuklarda görebiliriz. Kutucuklardaki ifadeler Base64 URL encoded şekilde kodlanarak “.” İle birleştirilir ve bu birleşimden bir JWS paketi oluşur. Servisler arası mesajlaşmalarda taşınacak veriler Şekil-1’deki gibi paketlenmiş halde bütünsel olarak iletilir.

JWS’yi oluşturan alt parçaların detaylarına bakmak gerekirse;
- Header (Başlık):
Json formatında yazılır ve içerisinde iki alan barındırır. Bunlar imzalama aşamasında kullanılan algoritma bilgisi ve token tipi alanlarıdır. Signature oluşturulurken ve doğrulanırken bu alanda taşınan bilgilere göre hesaplama yapılır. Header parçası base64 URL kodlaması yapılarak JWS’ye eklenir.
Header içerisinde taşıdığımız algoritma seçiminde farklı tercihler olabilir. Yaygın olarak SHA-256 HMAC veya RSA kullanılabilmektedir. Bu noktada önemli olan, şifreleme yaparken kullandığımız anahtar uzunluğunun güvenlik ve performans kriterlerine uygun olarak seçilmesi ve güvenli bir kaynakta saklanmasıdır. Tabii ki şifrelemede kullanıyor olduğumuz anahtar bilgileri, mesajı ileteceğimiz sistemde kullanılan anahtar ile uyumlu olmalı ve paydaşlar arasında key paylaşımları yapılmış olmalıdır.
- Payload (Veri):
Payload alanında istek gövdesi dediğimiz ve asıl iletecek olduğumuz Json verisi bulunmaktadır. Benzersizliği sağlamak amacıyla body içerisindeki bilgilerde Id gibi bir değer bulundurulmalıdır. Bu parça yine base64 URL encoded şekilde kodlanarak JWS içerisine eklenmektedir.
- Signature (İmza):
Signature JWS’nin son parçasıdır. İmza kontrolü ile doğrulama yapmamızı ve veri bütünlüğünü yönetmemizi sağlar. Header’deki algoritma bilgisi ile JWS içerisindeki ilk 2 parçayı kullanarak imzalama yapılır ve 3. parça olan signature oluşturulur.
JWS’ye dışarıdan müdahale edilirse signature hesabında kullanılan veriler değişeceği için imza da değişmiş olur böylelikle kendi tarafımızda oluşturduğumuz imza ile JWS içerisinde bulunan imzayı kıyaslayarak verinin manipüle edilip edilmediğini anlayabiliriz.

JWS’nin Kullanım Şekli:
1) JWS’yi oluşturuken:
Güvenli kaynakta saklanan key bilgilerini ve istek bodysini kullanarak bir JWS paketi oluşturulur. Şekil 3’teki metod içerisindeki aksiyonlar incelendiğinde şu işlemlerin yapılmış olduğu görülebilir:
Öncelikle header nesnesi oluşturularak içerisinde algoritma bilgisi atanır, Json formata serialize edildikten sonra Base64 URL encode edilerek ilk parça oluşturulur.
İkinci olarak istek body’si Json formatta alınır ve Base64 URL encode edilerek payload kısmı oluşturulur.
Son olarak imzanın oluşturulması için header ve payload birleştirilir, bu veri anahtar (macHashingKey) kullanılarak, header içerisindeki algoritmaya uygun formatta şifrelenerek imza elde edilir.
189. satırda oluşturulan parçalar birleştirilerek JWS’ye dönüştürülür.

Şekil 4’te ise aynı işlemin Jose-JWT nuget paketinden yararlanılarak yazılmış versiyonunu görüyoruz. RSA anahtarı kullanılarak yazılan bu versiyonda 218. satırdaki Jose.JWT.Encode metodu ilgili verileri encode ederek hazır bir JWS paketine dönüştürür.

JWS paketi post edilirken web request başlığındaki content-type parametresi “application\jose” olarak set edilmelidir.
2) JWS’yi doğrularken:
Response olarak bir JWS paketi aldığımızda öncelikle gelen verinin 3 parçasını elde ederiz. Header alanındaki algoritma bilgisini tespit edip bu algoritmaya göre yeni bir imza oluşturarak, JWS içerisindeki iletilen imza ile kıyaslama yaparız. İmzalar aynı değilse veri güvenliği sağlanamayacağından işleme devam etmeyiz.
Signature verify adımı için aşağıdaki kod bloğunu inceleyebiliriz. Gelen JWS içerisindeki ilk 2 alan, elimizde bulunan anahtar kullanılarak, header içerisindeki algoritma bilgisine göre imzalanmıştır. 262. satırda JWS’de iletilen signature ile kendi ürettiğimiz signature kıyaslanarak veride bozulma olup olmadığı kontrol edilmiştir.

JWS’nin Kullanım Alanları ve Avantajları:
JWS kullanımı ile veri akışı daha hızlı ve güvenli hale gelir. Yetkilendirme (Authorization) işlemlerinde kullanılması, veri tabanı ile bağlantı kurmaya gerek kalmaksızın doğrulama yapılabileceğinden dolayı avantaj sağlayabilir. Farklı programlama dillerinde destekleniyor olması geliştiricilere kolaylık sağlar.
Aşağıda bazı kullanım alanlarını sıralayabiliriz:
- Kimlik doğrulama: Bir kullanıcıyı doğrulayabilmek için kullanıcının kimlik bilgileri bir JWS ile imzalanabilir ve sunucu tarafında doğrulanabilir.
- Veri Bütünlüğü: Verinin değişip değişmediğini tespit etmek amacıyla birçok alanda kullanılabilir.
- API Güvenliği: Restful API’lerde güvenlik için kullanılabilir. API talebi JWS ile imzalanabilir ve sunucu, talebi doğrulayarak yetkisiz erişimleri engelleyebilir.
- Mobil Uygulama ve IoT Güvenliği: Mobil uygulama taleplerinde ve IoT cihazları arasındaki veri alışverişinde verilerin doğruluğunu sağlamak için kullanılabilir.
Referanslar:
https://openid.net/specs/draft-jones-json-web-signature-04.html (Erişim: 14.04.2023)
https://research.securitum.com/jwt-json-web-token-security/ (Erişim: 14.04.2023)
https://ambassadorpatryk.com/2020/07/secure-calls-from-salesforce-to-mulesoft-with-jwt/ (Erişim: 16.04.2023)