Gereksinimler ve Ön Hazırlık
Bu uygulamayı hayata geçirmek için modern bir .NET geliştirme ortamına ihtiyacınız var. Çalışmalarımızı .NET 9 veya üzeri sürümlerle uyumlu olacak şekilde yapılandıracağız. Sisteminizde yüklü olması gereken temel araçlar şunlardır:
- SDK: .NET 9.0 SDK veya daha güncel bir sürüm.
- IDE: Visual Studio 2022 (v17.12+) veya Visual Studio Code.
- Kütüphaneler: Sistemin kendi içerisinde gelen
System.Security.Cryptographykütüphanesi yeterlidir; harici bir bağımlılığa gerek yoktur.
Geliştirme sürecinde "Asimetrik Şifreleme" mantığını anlamak kritiktir. Bir özel anahtar (private key) ile imzalanan veri, sadece ilgili genel anahtar (public key) ile doğrulanabilir. Bu, verinin "inkar edilemezliğini" (non-repudiation) garanti altına alır.
Dijital İmza Servisi İçin Temel Yapılandırma
İlk adımda, dijital imza oluşturma ve doğrulama işlemlerini yönetecek olan DigitalSignatureService sınıfımızı oluşturacağız. Bu sınıf, RSA (Rivest-Shamir-Adleman) algoritmasını temel alacaktır. RSA, günümüzde dijital imzalar için endüstri standardı olarak kabul edilen asimetrik bir algoritmadır.
using System.Security.Cryptography;
using System.Text;
public class DigitalSignatureService
{
private readonly RSA _rsa;
public DigitalSignatureService(RSA rsa)
{
_rsa = rsa;
}
public byte[] SignData(string data)
{
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
return _rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
Burada SignData metodu, metin verisini byte dizisine dönüştürür ve SHA256 hashing algoritmasını kullanarak imzalama işlemini gerçekleştirir. RSASignaturePadding.Pkcs1 kullanımı, eski sistemlerle uyumluluk sağlayan standart bir dolgu yöntemidir.
Adım Adım İmza Doğrulama Mekanizması
İmza oluşturulduktan sonra, karşı tarafın bu imzayı doğrulaması gerekir. Doğrulama servisi, verinin orijinal olup olmadığını ve imzanın gerçekten iddia edilen sahibi tarafından atılıp atılmadığını kontrol eder. Aşağıdaki kod bloğu, doğrulama işleminin nasıl yapılacağını göstermektedir.
public bool VerifySignature(string data, byte[] signature)
{
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
return _rsa.VerifyData(dataBytes, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
Bu metot, orijinal veriyi ve dijital imzayı girdi olarak alır. VerifyData fonksiyonu, dahili olarak imza ile veriyi eşleştirir ve doğrulama başarılı ise true, aksi takdirde false döner.
Kriptografik Anahtar Yönetimi ve Güvenlik
Anahtarların güvenliği, sistemin güvenliğidir. Özel anahtarlarınızı asla kod içerisinde sabit (hardcoded) olarak tutmamalısınız. Üretim ortamlarında (production) Azure Key Vault, AWS KMS veya HashiCorp Vault gibi anahtar yönetim servislerini kullanmanız zorunludur.
Kritik Güvenlik Uyarısı: Özel anahtarları (Private Key) asla sürüm kontrol sistemlerine (Git vb.) yüklemeyin. Anahtarların sızması durumunda tüm imza sisteminiz geçersiz kalacaktır. Anahtarlarınızı şifrelenmiş ortamlarda ve erişim kısıtlaması olan yerlerde saklayın.
Aşağıdaki örnek, anahtarların nasıl dışarıdan yüklenebileceğini göstermektedir:
public void LoadKeys(string publicKeyXml)
{
_rsa.FromXmlString(publicKeyXml);
}
Yöntemlerin Karşılaştırmalı Analizi
Dijital imzalama işlemlerinde kullanılan farklı yaklaşımları ve kullanım alanlarını aşağıdaki tabloda özetledik:
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| RSA (PKCS#1) | Geniş uyumluluk, standart. | Anahtar boyutu büyüdükçe performans düşer. |
| ECDSA | Daha küçük anahtar, yüksek performans. | Eski sistemlerde destek sorunu olabilir. |
Yaygın Hatalar ve Debug İpuçları
En sık karşılaşılan hata, imzalama ve doğrulama sırasında kullanılan HashAlgorithmName veya Padding modlarının uyuşmamasıdır. Eğer doğrulama her zaman false dönüyorsa, şu adımları izleyin:
- Verinin imza anındaki encoding türü (UTF8, ASCII vb.) ile doğrulama anındaki türünün aynı olduğundan emin olun.
- Kullanılan hashing algoritmasının (SHA256, SHA512) her iki tarafta da aynı olduğunu teyit edin.
- RSA anahtarının imzalama için kullanılan özel anahtar mı yoksa doğrulama için kullanılan genel anahtar mı olduğunu kontrol edin.
// Hatalı kullanım örneği: Farklı padding kullanımı
// SignData için: RSASignaturePadding.Pkcs1
// VerifyData için: RSASignaturePadding.Pss (Bu işlem başarısız olur!)
Sıkça Sorulan Sorular
Dijital imza ile şifreleme arasındaki fark nedir?
Şifreleme veriyi gizlemek için kullanılır; imzalama ise verinin bütünlüğünü ve kimliğini doğrulamak için kullanılır. İmza, veriyi şifrelemez, sadece "mühürler".
SHA256 yerine neden başka bir algoritma kullanmayayım?
SHA256, günümüz donanımları için hız ve güvenlik dengesi açısından en güvenilir standarttır. SHA1 gibi eski algoritmalar artık "kırılabilir" kabul edildiği için kullanılmamalıdır.
İmza doğrulama servisi her istekte çalışmalı mı?
Evet, eğer API güvenliğiniz kritikse, her gelen istekte verinin değiştirilmediğini doğrulamak için imza kontrolü yapılmalıdır.
Performans kaybını nasıl önlerim?
Kriptografik işlemler CPU yoğunlukludur. Çok yüksek trafikli sistemlerde, imza doğrulama işlemini asenkron (async) olarak yönetmeli ve anahtar nesnelerini (RSA instance) yeniden oluşturmak yerine singleton olarak kullanmalısınız.
Üretim ortamında RSA anahtar uzunluğu ne olmalı?
2026 standartları gereği en az 3072-bit veya 4096-bit RSA anahtarları tercih edilmelidir. 2048-bit artık minimum güvenlik sınırı olarak görülmektedir.
Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Kriptografik sistemlerinizi üretim ortamına almadan önce bağımsız bir güvenlik denetiminden geçirmenizi ve güncel güvenlik standartlarını (NIST vb.) takip etmenizi öneririm.
ASP.NET Core Middleware ile Otomatik İstek Doğrulama
Kriptografik imza doğrulama servisini her controller metodunda manuel olarak çağırmak yerine, ASP.NET Core'un Middleware yapısını kullanarak bu süreci merkezi bir hale getirebilirsiniz. Bu yaklaşım, kod tekrarını önler ve uygulamanızın güvenlik katmanını standartlaştırır.
Aşağıdaki örnek, gelen HTTP isteklerinin header kısmında yer alan "X-Signature" değerini, istek gövdesi (body) ile karşılaştıran bir ara katman yapısını göstermektedir:
public class SignatureValidationMiddleware
{
private readonly RequestDelegate _next;
private readonly ISignatureService _signatureService;
public SignatureValidationMiddleware(RequestDelegate next, ISignatureService signatureService)
{
_next = next;
_signatureService = signatureService;
}
public async Task InvokeAsync(HttpContext context)
{
context.Request.EnableBuffering();
var signature = context.Request.Headers["X-Signature"].FirstOrDefault();
using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
var body = await reader.ReadToEndAsync();
context.Request.Body.Position = 0;
if (string.IsNullOrEmpty(signature) || !_signatureService.VerifySignature(body, signature))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync("Geçersiz veya eksik dijital imza.");
return;
}
await _next(context);
}
}
Kriptografik Performans Optimizasyonu ve Önbellekleme
Yüksek trafikli sistemlerde, her istekte RSA imza doğrulama işlemi yapmak CPU üzerinde ciddi bir yük oluşturabilir. Doğrulama sürecini optimize etmek için şu stratejileri uygulayabilirsiniz:
- Public Key Önbellekleme: RSA anahtarını her doğrulama işleminde dosyadan okumak yerine, uygulama başlangıcında yükleyip bellekte (Singleton olarak) tutun.
- Hızlı Başarısızlık (Fail-Fast): İmza formatı (Base64) veya uzunluğu hatalı olan istekleri, kriptografik işleme sokmadan doğrudan reddedin.
- Zaman Damgası (Timestamp) Kontrolü: İstek gövdesine bir zaman damgası ekleyerek, "Replay Attack" (Yeniden Oynatma Saldırısı) riskini minimize edin. Eğer istek üzerinden belirli bir süre (örneğin 5 dakika) geçmişse, imzayı doğrulamadan reddedin.
Replay Attack Koruması İçin Örnek Mantık
İstek gövdesine ekleyeceğiniz bir "nonce" veya "timestamp" alanı, imza bütünlüğünü korurken aynı zamanda isteğin tazeliğini de denetlemenizi sağlar:
public bool IsTimestampValid(string requestBody)
{
var data = JsonSerializer.Deserialize(requestBody);
var requestTime = DateTimeOffset.FromUnixTimeSeconds(data.Timestamp);
// İstek 5 dakikadan daha eskiyse reddet
return (DateTimeOffset.UtcNow - requestTime).TotalMinutes < 5;
}
Bu yöntem, saldırganın yakaladığı geçerli bir imzalı paketi daha sonra tekrar göndererek sisteminizi manipüle etmesini engeller. Kriptografik sistemlerde sadece imza doğruluğu değil, isteğin bağlamı da güvenlik için kritik bir parametredir.
Sonuç
C# ile özel bir kriptografik imza doğrulama servisi oluşturmak, uygulamanızın güvenliğini bir üst seviyeye taşır. Bu rehberde, RSA algoritmasını kullanarak güvenli bir imzalama ve doğrulama altyapısını nasıl kuracağınızı, anahtar yönetiminin önemini ve sık yapılan hataları ele aldık. Bir sonraki adım olarak, bu servisi bir ASP.NET Core Middleware içerisine entegre ederek, gelen tüm HTTP isteklerini otomatik olarak doğrulayan bir yapı kurmayı deneyebilirsiniz.


Yorumlar (0)
Yorum Yaz