Gereksinimler ve Ön Hazırlık
Bu uygulamayı geliştirmek için modern bir .NET geliştirme ortamına ihtiyacınız vardır. Aşağıdaki araçların sisteminizde kurulu olduğundan emin olun:
- .NET 9 SDK veya üzeri.
- Visual Studio 2022 (v17.12+) veya Visual Studio Code (C# Dev Kit eklentisi ile).
- Temel düzeyde asimetrik şifreleme ve dijital imza mantığı bilgisi.
Projenizi başlatmak için terminal üzerinden dotnet new console -n KriptoDogrulamaServisi komutunu kullanarak standart bir konsol uygulaması oluşturabilir veya mevcut bir ASP.NET Core projesine entegre edebilirsiniz.
Dijital İmza Mantığı ve RSA Algoritması
Dijital imza, bir mesajın göndericisine ait olduğunu ve mesajın yolda değiştirilmediğini kanıtlayan matematiksel bir şemadır. RSA algoritması, bir Özel Anahtar (Private Key) ile imzalama ve bir Açık Anahtar (Public Key) ile doğrulama prensibine dayanır. İmza doğrulama servisi, verinin kendisini, dijital imzayı ve göndericinin açık anahtarını girdi olarak alır.
Aşağıdaki tabloda, kriptografik imzalama yöntemlerinin karşılaştırmasını bulabilirsiniz:
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| RSA (PKCS#1 v1.5) | Geniş uyumluluk | Daha yavaş işlem |
| RSA (PSS) | Daha güvenli (modern) | Daha karmaşık yapı |
| ECDSA | Hızlı ve düşük boyutlu | Daha yeni standart |
Adım 1: RSA Anahtar Çifti Oluşturma
İmza doğrulama servisine geçmeden önce, testleriniz için bir anahtar çifti oluşturmalısınız. Bu anahtarlar, verinin doğrulanması için temel teşkil eder.
using System.Security.Cryptography;
public static class AnahtarUretici {
public static (string publicKey, string privateKey) AnahtarCiftiOlustur() {
using var rsa = RSA.Create(2048);
var publicKey = rsa.ExportRSAPublicKeyPem();
var privateKey = rsa.ExportRSAPrivateKeyPem();
return (publicKey, privateKey);
}
}
Yukarıdaki kod, 2048 bit uzunluğunda bir RSA anahtar çifti oluşturur. ExportRSAPublicKeyPem metodu, anahtarı standart PEM formatında dışa aktarır, bu da diğer sistemlerle kolayca paylaşılmasını sağlar.
Adım 2: Veriyi İmzalama Servisi
Doğrulama işlemini test edebilmek için önce bir veriyi imzalamamız gerekir. İmzalama işlemi, verinin bir hash değerinin özel anahtar ile şifrelenmesidir.
public static byte[] VeriImzala(string veri, string privateKeyPem) {
using var rsa = RSA.Create();
rsa.ImportFromPem(privateKeyPem);
var veriBytes = System.Text.Encoding.UTF8.GetBytes(veri);
return rsa.SignData(veriBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
Burada SignData metodu, veriyi SHA256 algoritması ile özetler ve ardından özel anahtar ile imzalar. RSASignaturePadding.Pkcs1, yaygın kullanılan imzalama standardıdır.
Adım 3: İmza Doğrulama Servisi Geliştirme
Şimdi ana konumuz olan doğrulama servisini yazalım. Bu servis, gelen imzanın, verinin ve açık anahtarın eşleşip eşleşmediğini kontrol eder.
public class ImzaDogrulayici {
public bool Dogrula(string veri, byte[] imza, string publicKeyPem) {
using var rsa = RSA.Create();
rsa.ImportFromPem(publicKeyPem);
var veriBytes = System.Text.Encoding.UTF8.GetBytes(veri);
return rsa.VerifyData(veriBytes, imza, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
VerifyData metodu, veriyi ve imzayı alır. Eğer imza, belirtilen açık anahtar ile doğrulanırsa true döner. Bu işlem, verinin yolda değiştirilmediğini garanti eder.
Kritik Güvenlik Uyarısı: Üretim ortamında anahtarlarınızı asla kod içerisinde hard-coded (sabit) olarak tutmayın. Azure Key Vault, AWS KMS veya HashiCorp Vault gibi güvenli anahtar yönetim servislerini kullanın.
Adım 4: Servisi Test Etme ve Hata Ayıklama
Servisimizin doğru çalışıp çalışmadığını anlamak için bir entegrasyon testi yapalım. Aşağıdaki örnek, doğru ve yanlış senaryoları kapsar.
var (pub, priv) = AnahtarUretici.AnahtarCiftiOlustur();
var veri = "Bu gizli bir mesajdır.";
var imza = VeriImzala(veri, priv);
var dogrulayici = new ImzaDogrulayici();
bool sonuc = dogrulayici.Dogrula(veri, imza, pub);
Console.WriteLine($"İmza Geçerli mi? {sonuc}"); // Çıktı: True
Eğer veriyi veri = "Değiştirilmiş mesaj"; şeklinde değiştirirseniz, Dogrula metodu false dönecektir. Bu, kriptografik bütünlük kontrolünün başarıyla çalıştığını gösterir.
Yaygın Hatalar ve İpuçları
Geliştirme sırasında en sık karşılaşılan hatalar şunlardır:
- Encoding Sorunları: İmzalama ve doğrulama sırasında veriyi farklı encoding (UTF8, ASCII vb.) türleriyle dönüştürmek imza uyumsuzluğuna yol açar. Her zaman UTF8 kullanın.
- Padding Uyumsuzluğu: İmzalarken
Pkcs1kullandıysanız, doğrulamada daPkcs1kullanmalısınız. - Anahtar Formatı: PEM formatı dışındaki anahtarları
ImportFromPemile okumaya çalışmak hata fırlatır.
Sıkça Sorulan Sorular
Dijital imza ile şifreleme aynı şey midir?
Hayır. Şifreleme veriyi gizlemek için kullanılır; dijital imza ise verinin bütünlüğünü ve kaynağını doğrulamak için kullanılır.
RSA 2048 bit yeterli mi?
2026 yılı standartları için RSA 2048 bit genel kullanımlar için güvenli kabul edilir. Ancak yüksek güvenlik gerektiren finansal sistemlerde 3072 veya 4096 bit tercih edilmelidir.
Neden SHA256 kullanıyoruz?
SHA256, güncel kriptografik standartlarda çarpışma direnci (collision resistance) en yüksek ve yaygın desteklenen özetleme algoritmalarından biridir.
İmza doğrulama servisi yavaş mı çalışır?
Asimetrik işlemler CPU yoğunlukludur. Çok yüksek trafikli sistemlerde imza doğrulamayı bir önbellek (caching) mekanizması ile optimize etmelisiniz.
Hangi durumlarda imza geçersiz sayılır?
Veri üzerinde tek bir baytlık değişiklik olsa bile, imza ile veri eşleşmeyeceği için doğrulama başarısız olur.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Kriptografik sistemlerin güvenliği, sadece kodun değil, anahtar yönetimi ve altyapı güvenliğinin de bir bütünüdür. Üretim ortamına geçmeden önce güvenlik denetimlerinden geçmeniz önerilir.
Performans Optimizasyonu ve Anahtar Yönetimi Stratejileri
Kriptografik imza doğrulama süreçleri, özellikle yüksek trafikli sistemlerde CPU üzerinde ek yük oluşturabilir. RSA gibi asimetrik algoritmalar, simetrik algoritmalara göre daha yoğun işlem gücü gerektirir. Performansı optimize etmek için şu stratejileri uygulayabilirsiniz:
- Anahtar Önbellekleme: Public anahtarları her doğrulama işleminde diskten veya veritabanından okumak yerine,
MemoryCachekullanarak bellekte tutun. - Anahtar Boyutu Seçimi: 2048-bit RSA günümüz standartları için güvenli ve performanslıdır. 4096-bit anahtarlar güvenlik seviyesini artırsa da doğrulama süresini ciddi oranda yavaşlatabilir.
- Asenkron İşlemler: I/O bağımlı işlemlerde (anahtar yükleme gibi) mutlaka
async/awaitdesenini kullanarak uygulama thread havuzunu koruyun.
Aşağıdaki örnek, anahtarın bellekte nasıl güvenli bir şekilde önbellekleneceğini göstermektedir:
public class KeyCacheService
{
private readonly IMemoryCache _cache;
public KeyCacheService(IMemoryCache cache) => _cache = cache;
public RSA GetPublicKey(string keyId)
{
return _cache.GetOrCreate(keyId, entry =>
{
entry.SlidingExpiration = TimeSpan.FromHours(1);
var rsa = RSA.Create();
rsa.FromXmlString(LoadKeyFromSecureVault(keyId));
return rsa;
});
}
private string LoadKeyFromSecureVault(string id) => "---PUBLIC KEY DATA---";
}
Üretim Ortamında Deployment ve Güvenlik İpuçları
Uygulamanızı canlı ortama alırken, kriptografik anahtarların yönetimi en kritik güvenlik katmanıdır. Kod içerisinde hard-coded (sabit) anahtar tutmak, sistemin güvenliğini temelden sarsar. Bunun yerine aşağıdaki kurumsal yaklaşımları benimseyin:
- Key Vault Kullanımı: Azure Key Vault, AWS KMS veya HashiCorp Vault gibi servisleri kullanarak anahtarlarınızı uygulama kodundan tamamen ayırın.
- Anahtar Rotasyonu: Belirli aralıklarla (örneğin 6 ayda bir) anahtar çiftlerini yenileyin. Sisteminizin birden fazla aktif public anahtarı destekleyecek şekilde tasarlanması, kesintisiz rotasyon sağlar.
- Çevre Değişkenleri: Geliştirme ortamında bile olsa anahtarları
appsettings.jsondosyasına değil,User Secretsveya ortam değişkenlerine yerleştirin.
İmza doğrulama servisinizi bir ASP.NET Core Middleware olarak kurgulamak, API güvenliğinizi merkezileştirir. Bu sayede her endpoint için ayrı doğrulama mantığı yazmak yerine, gelen HTTP isteklerinin header kısmındaki X-Signature değerini otomatik kontrol edebilirsiniz:
public class SignatureMiddleware
{
private readonly RequestDelegate _next;
public SignatureMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var signature = context.Request.Headers["X-Signature"].FirstOrDefault();
if (string.IsNullOrEmpty(signature) || !ValidateSignature(context.Request.Body, signature))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Geçersiz veya eksik imza.");
return;
}
await _next(context);
}
private bool ValidateSignature(Stream body, string signature)
{
// Doğrulama mantığı buraya gelir
return true;
}
}
Önemli Not: Middleware içerisindecontext.Request.Bodyakışını okurken, isteğin daha sonra controller tarafından okunabilmesi içincontext.Request.EnableBuffering()metodunu çağırmayı unutmayın. Aksi takdirde, gövde verisi tüketildiği için controller'a boş veri gidecektir.
Sonuç
C# ile özel bir kriptografik imza doğrulama servisi oluşturmak, .NET platformunun sunduğu güçlü System.Security.Cryptography kütüphanesi ile oldukça verimli bir süreçtir. Bu rehberde, anahtar üretiminden imza doğrulamaya kadar olan süreci adım adım inceledik. Bir sonraki adım olarak, bu servisi bir ASP.NET Core Middleware yapısına dönüştürerek gelen tüm HTTP isteklerini otomatik olarak doğrulayan bir yapı kurmayı deneyebilirsiniz.


Yorumlar (0)
Yorum Yaz