GAME, SOFTWARE, NETWORKING AND MORE...

Contact us for cooperation

 

Unity - Mobil İçin Güvenlik

İnternet çağı boyunca güvenlik her zaman sorun olmuştur ve olmaya devam edecektir. Bu yazımda; mobil uygulamanızı, kötü niyetli insanların uygulamanıza yapmak istedikleri kötü şeylerden(*) korumanız için güvenlik tavsiyeleri vereceğim. Yalnız şunu baştan belirtmeliyim ki bu yazdıklarımın hepsini harfiyen uygulasanız bile uygulamanız %100 güvenli olmaz, sadece kötü niyetli insanların işlerini olabildiğince zorlaştırırsınız. Unutmayın; hiç bir sistem güvenli değildir :)

1-) IL2CPP İle Build Alın

Normalde Mono(C#) ile build aldığınız apk(android) ve ipa(ios) dosyalarını decompile ederseniz içlerinde Assembly-CSharp.dll gibi bir takım dll dosyası görürsünüz. Bu dll dosyalarını ILSpy gibi yazılımlarla decompile ederseniz, projenizde kullandığınız bütün c# kodlarını biraz düzensiz bir biçimde görürsünüz. Düzensiz ama okunamaz değil:) Ama IL2CPP ile build alırsanız, projenizdeki bütün C# scriptleri c++ a dönüştürülür ve öyle build alınır. C++ tan oluşturulmuş dll dosyalarının decompile edilmesi çok zordur, nedeni ise direk makine kodu içermesi.

2-) Kritik Verilerinizi Olabildiğince Değişkenlerde Tutmayın

Örneğin oyuncunun altın sayısını değişkende tutmak yerine, her lazım olduğunda nerde tutuyorsanız ordan çekin. Mesela PlayerPrefs kullanıyorsanız, altın artırırken direk PlayerPrefs ile altın değişkenini önce çekip sonra üstüne ekleme yapıp sonra da kayıt edin PlayerPrefs ile. Altını değişkende tutup ta, o değişkeni artırıp daha sonra PlayerPrefs ile kayıt etmeyin, çünkü değişkenler ram'de tutulur ve o değişkenlere üçüncü taraf yazılımlarla erişmek gerçekten çok kolay:)

3-) Verilerinizi Local'de Tutuyorsanız Mutlaka Şifreleyin

Normal tek yönlü şifrelemeden bahsetmiyorum, simetrik şifreleme yöntemlerinden birini kullanın. DES, Triple DES, RC2 ve Rijndael simetrik şifreleme yöntemleridir. Bunlar arasında önerdiğim Rijndael'dir çünkü mono'da en hızlı çalışan o. Rijndael ile bir veriyi, bir kullanıcı adı ve şifre kullanarak encypt(şifrelemek) edebilir ve şifrelenmiş veriyi sadece aynı kullanıcı adı ve şifreyle decrypt(şifre çözme) edebilirsiniz. Mesela PlayerPrefs kullanıyorsanız hem key'i hem de data'yı Rijndael ile şifreleyip öyle kayıt ederseniz, kötü niyetli kullanıcı hafızadan PlayerPrefs'lerin kayıtlı olduğu dosyayı bulsa bile şifreli veriden hiç bir şey anlamayacaktır. Şifreli veriye müdahale ederse ve oyuna girerse, oyun şifrelenmiş data'yı çözemeyecek. Basit bir Try/Catch ile bunu yakalayıp kullanıcının hile yapıp yapmadığını anlayabilirsiniz. Artık ne ceza vereceğiniz size kalmış :)

4-) Asset Store'daki Güvenlik Araçlarını Kulanın

Bunun için iki asset önereceğim; Obfuscator ve Anti-Cheat Toolkit. Obfuscator asseti; yazdığınız kodlardaki bütün değişken, class, method, parametreler vs hepsini yeniden adlandırır ve random saçma isimler verir. Sadece bunu değil, ek olarak fake kodlar dahil eder build e. Bu şekilde kötü niyetli kullanıcının sizin kodları okumasını epey bir zorlaştırırsınız. Anti-Cheat Toolkit asseti ise, ram'deki değişkenlerin değerlerini şifreleyip ram'de gizlemeye yarıyor. Bütçeniz varsa bu iki asset'i projenizde kullanmanızı şiddetle tavsiye ediyorum.

Bundan sonraki maddeler sadece sunucu'ya/host'a bağlı uygulamalar için gereklidir(Sadece Online ya da Multiplayer'dan bahsetmiyorum). Ekstra güvenlik için sunucu tabanlı çalışmak çok büyük artılar kazandırır size!

5-) Veritabanına Bağlanmak İçin PHP/ASP Köprüsü Kullanın

Asla C#'tan doğrudan veritabanına bağlanmayın. Kötü niyetli kullanıcılara çok büyük bir açık vermiş olursunuz. Nedeni ise, veritabanı bilgilerinizin açık açık c#'ta kayıtlı kalması. Bütün veritabanınızı PHP ya da ASP'de sunucu içinde halletmeniz ve kullanıcının sadece sunucuya PHP yada ASP yolu ile talimat vermesi doğru bir yoldur.

6-) Kullanıcı, Verileri Sunucuya GET İle Göndermesin

POST ile göndersin. GET'te gönderilen veriler çok açıkta oluyor.

7-) Sunucuda SSL Sertifikası Kullanın

SSL; kullanıcı ile sunucu arasında güvenli bir bağlantı sağlar. Haberleşme şifreli olduğu için güvenlik için yine önemli bir unsur.

8-) Kullanıcının Sunucuya Attığı ve Sunucudan Aldığı Veriler Şifreli Olsun

Burada da yine simetrik şifreleme yöntemlerinden biri kullanılmalı. Kullanıcı veriyi sunucuya göndermeden önce simetrik şifreleme ile şifreleyip öyle göndermeli sunucuya. Sunucu şifreli veriyi aldıktan sonra şifreyi çözecek ve ona göre işlem yapacak. Şunu asla unutmayın ki kullanıcı-sunucu arasındaki veri alışverişi trafiği çok kolay bir şekilde üçüncü taraf yazılımlarla tespit edilebiliyor.

9-) Ayrıca Kullanıcının Attığı Veri'ye Zamanı da Dahil Edin

Veriyi şifreleyip sunucuya öyle atmak, bütün güvenlik problemini çözdüğümüz anlamına gelmiyor. Şöyle bir örnek vereyim; kullanıcı 10 altın ödülünü hak kazandı ve bunu sunucuya bildirmesi gerek o altınları alması için. Kullanıcı, "Ahmet_10_altin_kazandi"(tamamen örnek!) verisini çok güzel bir şekilde şifreleyip sunucuya attı, sunucu şifreyi çözüp Ahmet üyesine 10 altın vermesi gerektiğini anlıyor ve veriyor altınları. Peki ya Ahmet o an network trafiğini takip edip, sunucuya attığı şifreli veriyi bulup, o veriyi başka herhangi bir yazılımla ilgili post url'sine post ederse ne olur? Tebrik ederiz Ahmet, sınırsız altın toplama bug'ı buldun! Bunun ise üstesinden şöyle gelebiliriz; kullanıcı, sunucuya attığı her isteğe/veriye ek olarak anlık tarihi timestamp olarak atmalı. Timestamp sürekli değişeceği için dolaysıyla şifreli veri de değişmiş olacak her seferinde. Sunucu kullanıcıdan aldığı şifreli veriyi çözdükten sonra; kullanıcıdan aldığı timestamp'i, kullanıcının id'si ile birlikte veritabanına kayıt eder. Eğer o kullanıcı aynı şifreli data'yı göndermeye çalışırsa, sunucu veritabanından timestamp i ve o kullanıcının id'sini kontrol eder ve zaten o timestamp in daha önce veritabanına kayıtlı olduğunu görür. Bu durumda işlem yapmaz sunucu ve bu olayı da çözmüş oluruz :)

Güvenlik ile ilgili vereceğim tavsiyeler bu kadar. Bu güvenlik önlemlerinin projenizin performansına negatif yönde etki edeceğini unutmayın. Özellikle de 8 ve 9.madde. Yapacak bir şey yok, güvenlik istiyorsanız performastan ödün vereceksiniz :) Okuduğunuz için teşekkürler.