Xamarin Forms AES 256 Bit Şifreleme Kullanımı

Merhabalar,

Güzel bir bayram sabahı vakit bulabilmişken hemen bilgisayar başına oturup, aklımdaki konuyu yazmak istedim 🙂

Gelen maillerden anladığım kadarıyla Xamarin.Forms ile geliştirdiğimiz mobil uygulamalarımızda şifreleme ve şifre çözme işlemleri biraz havada kalmış. Amacım bu yazı ile bu soru işaretlerini ortadan kaldırmak.

Aslında yapacağımız işlem XF tarafında desteklenmeyen kütüphaneleri, DependencyService yardımıyla Traditional tarafta halledip, geriye bir object döndürmek 🙂

Şifreleme algoritması olarak AES 256 bit kullanacağım. Bu şifreleme algoritması konusundaki orjinal kaynağa linkten ulaşabilirsiniz.

Buradaki amacımız bu şifreleme yöntemlerinin XF tarafında nasıl kullanıldığını anlamak olduğu için AES algoritmasına ve çalışma mantığına pek değinmeyeceğim. Zaten kaynak linkinde yazan arkadaş konuyu gayet iyi anlatmış. Öğrenmek isteyenler kaynaktan detaylı bir şekilde okuyup, öğrenebilir.

Bu arada atlamadan geçmeyelim. XF PCL projelerinizde kullanabileceğiniz PCLCrypto plugini de var 🙂

Senaryomuz şu şekilde olsun. Kredi kartı bilgilerini XF ile geliştirdiğim mobil uygulamadan alıp, web servis yardımıyla son kullanıcının ödeme yapmasını sağlamak olsun.

Basit bir şekilde CreditCard sınıfı oluşturdum.

public class CreditCard
{
public string Number { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Month { get; set; }
public string Year { get; set; }
public string Cvv { get; set; }
public string InstallmentNumber { get; set; }
}

Amaç bu sınıfını kullanarak traditional tarafta gerekli yerleri AES algoritması ile şifrelemek ve tekrar PCL tarafta kullanmak.
Bu işlemi yapabilmek için yardımcı bir interface yaratmamız gerekiyor.

public interface ICreditCardCryptor
{
CreditCard AESEncryption(CreditCard card);
}

Şifresiz CreditCard sınıfını alıp, şifreledikten sonra tekrar CreditCard sınıfını dönecek olan interface’i oluşturmuş olduk.

Ufak bir ekran tasarımı yapalım 🙂

Android tarafı için başlayalım..

Crypto için bir şifreye ihtiyacımız var bunu hem iOS hem de Android tarafında kullanacağım için, App.cs altında public static string password = “XFAES”; static bir değişken tanımladım.

class CreditCartDependency : ICreditCardCryptor
{
public CreditCard AESEncryption(CreditCard card)
{
return new CreditCard
{
Name = EncryptText(card.Name, App.password),
Surname = EncryptText(card.Surname, App.password),
Cvv = EncryptText(card.Cvv, App.password),
InstallmentNumber = EncryptText(card.InstallmentNumber, App.password),
Month = EncryptText(card.Month, App.password),
Number = EncryptText(card.Number, App.password),
Year = EncryptText(card.Year, App.password)
};
}
public string EncryptText(string input, string password)
{
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
string result = Convert.ToBase64String(bytesEncrypted);
return result;
}
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
}

Kredi kartı bilgilerini web servise göndermeden hemen önce Traditional tarafta System.Security.Cryptography dll’i yardımıyla şifreliyoruz.

iOS tarafına geçelim..

class CreditCartDependency : ICreditCardCryptor
{
public CreditCard AESEncryption(CreditCard card)
{
return new CreditCard
{
Name = EncryptText(card.Name, App.password),
Surname = EncryptText(card.Surname, App.password),
Cvv = EncryptText(card.Cvv, App.password),
InstallmentNumber = EncryptText(card.InstallmentNumber, App.password),
Month = EncryptText(card.Month, App.password),
Number = EncryptText(card.Number, App.password),
Year = EncryptText(card.Year, App.password)
};
}
public string EncryptText(string input, string password)
{
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
string result = Convert.ToBase64String(bytesEncrypted);
return result;
}
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
}

Aslında Crypto classını tek bir sefer yazıp “add existing item” yardımıyla hem iOS hem de Android tarafta kullanabilirdik. Fakat olayı daha yalın bir şekilde aktarabilmek için o yöntemi uygulamadım.

Gelelim kullanımına..

private void Button_Clicked(object sender, EventArgs e)
{
var Crypto = DependencyService.Get<ICreditCardCryptor>()
.AESCrypto(new CreditCard
{
Cvv = txtCvv.Text,
Name = txtName.Text,
Surname = txtSurname.Text,
Number = txtNumber.Text,
InstallmentNumber = pckrInstallment.SelectedItem
.ToString(),
Month = pckrMonth.SelectedItem.ToString(),
Year = pckrYear.SelectedItem.ToString()
});
}


Test ettiğimizde şifreleme işlemlerimizin hem iOS hem de Android için sorunsuz çalıştığını göreceğiz.
Tabi bu işlemin bir de şifre çözme tarafı var.
Interface tarafına ufak bir update geçiyoruz..

public interface ICreditCardCryptor
{
CreditCard AESEncryption(CreditCard card);
CreditCard AESDecryption(CreditCard card);
}

Daha sonra Traditional tarafta gerekli geliştirmereli yapmalıyız.
iOS ve Android için..

public CreditCard AESDecryption(CreditCard card)
{
return new CreditCard
{
Name = DecryptText(card.Name, App.password),
Surname = DecryptText(card.Surname, App.password),
Cvv = DecryptText(card.Cvv, App.password),
InstallmentNumber = DecryptText(card.InstallmentNumber, App.password),
Month = DecryptText(card.Month, App.password),
Number = DecryptText(card.Number, App.password),
Year = DecryptText(card.Year, App.password)
};
}
public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
public string DecryptText(string input, string password)
{
byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
string result = Encoding.UTF8.GetString(bytesDecrypted);
return result;
}


Decrypt işlemlerimizin de başarılı bir şekilde gerçekleştiğini görüyoruz.

Kaynak kodları github üzerinden indirebilirsiniz.

Yiğit

Xamarin Developer, Consultant & Architect. Founder and Director of Xamarin Türkiye

Post A Reply

trabzon escort dns sunucusu yanıt vermiyor sex hikayeleri seks hikayeleri free porn tipobet aydın escort aydın escort balıkesir escort balıkesir escort bandırma escort bandırma escort manisa escort manisa escort marmaris escort marmaris escort nevşehir escort nevşehir escort niğde escort niğde escort