API Güvenliği: AES Veri Şifrelemesi

Talha Tarık Küçük
5bayt
Published in
4 min readApr 28, 2020

Merhaba, bu yazımda bir mobil uygulamayla servis arasında sorgu gönderimi, verilerin uygulamadan servise şifrelenerek gitmesi ve çözülmesi daha sonra servisten şifreli şekilde yanıt dönmesi ve uygulamada verilerin çözülmesi şeklinde bir senaryoyu ele alacağım.

Çalışmanın kodlarına buradan ulaşabilirsiniz.

UYGULAMA → request şifrelendi →SERVİS → request çözüldü →yanıt döndü → yanıt şifrelendi → UYGULAMA → yanıt çözüldü

Ben bu örneği python ile yapacağım. Öncelikle (python 3.6 için) pycryptodomexkütüphanelerini kuralım.

pip3 install pycryptodomex

Aşağıda basitçe string msg_text, secret key ile önce şifreleniyor sonra şifre aynı key ile çözülüyor. Aşağıda basit bir yapıda örneğini koydum ben AES — ECB ile şifreleme yapacağım.

import base64
from Cryptodome.Cipher import AES

msg_text = b'test some plain text here'.rjust(32)
secret_key = b'1234567890123456'

cipher = AES.new(secret_key,AES.MODE_ECB)
encoded = base64.b64encode(cipher.encrypt(msg_text))
print(encoded)
decoded = cipher.decrypt(base64.b64decode(encoded))
print(decoded)

Senaryo gereği API adreslerimiz aşağıdaki gibi olsun. API için Python Flask kullanacağım.

Bunlar POST metodları olsun.

deviceId →Mobil cihazların unique numaraları cihazın login olduktan sonra, aynı cihazdan yapılan işlemlere izin verir.

userId → Kullanıcıya ait unique no.

/profile/list/followers [POST]  [deviceId=][userId=]
/profile/list/follows [POST] [deviceId=][userId=]

Şimdi yukarıdaki olması gereken yapı ancak ben POST olarak belirttiğim yapıyı değiştirerek aşağıdaki hale getiriyorum.

/ [POST]  [api=]

Burada api=’işlem_stringi’

İşlem stringi içeriği aşağıdaki gibi olacak:

methodName&deviceId&userId (örnek: ProfileListFollowers&1&1)

Şimdi biraz proje üzerinden gideceğim. Projeyi aşağıdaki dizin sıralamasıyla oluşturuyorum.

--Start.py--AES
- AES.py
-__init__.py
--API
-APIGateway.py
-__init__.py

Start.py (Flask Start)

Flask’i ayağa kaldıran Start.py ile başlayalım. API “/” örneğin lokalhost:5000/ üzerine POST veri gönderebilir.

Mobil taraftan şifrelenmiş olarak gelen veriyi getDecode ile çözüyorum. Ben şifrelenmiş olarak “ProfileListFollowers&1&1" gönderdiğim için şifreyi çözüp & ile split yapmasını bekliyorum. Gönderdiğim tüm sorguların 0.Elemanı MetodAdı 1.Elamanını da DeviceId olarak belirledim. Bundan sonraki elemanlar processlerinize göre değişecektir.

Mobil uygulama için öncelikle Unique deviceId ile daha bu cihazdan aktif login olunmuş mu kontrolü yapıyorum. (Örnek olduğu için Auth sürekli True dönmektedir.) Bu kontrol sonrası 0.elemanın yani metod adını kontrol ediyorum ve metod yönlendirmesi yapıyorum. 2.eleman olarak da UserId’yi gönderdiğim için senaryo gereği bir kişinin takipçilerini json dönen process çalışacak.

AES/AES.py

Burada getKeyGenerator şifre çözme anahtarı oluşturuyor. Örneğin ReactNative bir mobil uygulamanız var orada da POST ettiğiniz verileri bu tipte sizin belirlediğiniz özelliklerde anahtarlar oluşturabilirsiniz. Ben basit şekilde oluşturdum. Ancak örneğin şunu yapabilirsiniz post ederken tarih saat bilgisini gönderip tarih saat bilgilerinden istediğiniz gibi kombinasyonla anahtar oluşturup şifreleyip aynı anahtarı servis tarafında da oluşturarak veriyi çözebilirsiniz. Dikkat edilmesi gereken benim kullandığım tip için 16 karakter olması. Ben aşağıdaki anaharda belli bir mantığa göre 15 digit bir key oluşturdum bunu 16 ya tamamlamak için de 0 ekledim. İkinci önemli nokta getDecode metodu, burada şifre çözme işlemi yapılır. Key oluşturma metodu buradan çağrılır. Üçüncü önemli nokta getEncode yani şifreleme. Şifrelemeyi bir örnek yapabilmek için yazdım. Ancak şifrelemeyi örneği reactnative bir uygulamanız varsa uygulama içinde yapmanız gerekecek.

API/APIGateway.py

API’de Auth ile Start.py aşamasında belirttiğim işlemleri yapıyorum. Bunun dışındaki diğer metodlar da isteğe bağlı Start.py’den yönlendirilerek çağrılmaktadır.

Şimdi POSTMAN ile bir deneme yapalım…

Aslında şifreleme işlemini uygulama tarafında oluşturmak gerek ancak ben basit bir örnek yapacağım. ReactNative için AES kütüphanelerini en altta paylaşmış olacağım…

ŞİFRELENMİŞ VERİ OLUŞTURMA

ProfileListFollowers&1&1 isteğini şifreledim. Şifrelenmiş sonucu kopyaladım.

localhost:5000/’e key:api value: şifrelenmiş veriyi POST ettiğimde şifre servis tarafında çözüldü ve sonuç döndü.

POSTMAN İLE API TEST

Dipnot…

Yukarıdaki işlemi aynı gün içinde yaparsam(örneğin cihazların veri trafiğinin takip edildiğini düşünelim) bir kullanıcı için sürekli aynı sonuçları dönecektir. Ancak burada şifrelemeyi saniye bazında yaparsam yanı api=şifrelenmiş veri && time=datetime gönderirsem ve time ile ilgili karmaşık bir şifreleme yaparsam her sorgu yalnız bir defa çalışmış olur. Çünkü işin içine zaman kavramı giriyor. Benim yukarıda oluşturduğum veri gün bazında bir veri ve o gün için oluşturulmuş bir şifrelenmiş sorguydu…

ReactNative için AES şifrelemesi yapabileceğiniz bazı kütüphaneler…

Başka bir yazıda görüşmek üzere…

--

--