NodeJS ile Veri Şifreleme için Başlangıç Kılavuzu

Fatih Küçükkarakurt

Fatih Küçükkarakurt

7 min read

Web geliştirme şifreleme olmadan hayatta kalamaz.

Web uygulamaları insanlara, kuruluşlara ve hatta hükümetlere ait büyük miktarlarda hassas verilere erişmeye devam ettikçe, haliyle veri güvenliğine yönelik tehdit de tüm zamanların en yüksek seviyesinde. Programcılar, programlamanın ilk günlerinden beri bu tür hassas verileri kötü niyetli kişilere karşı korumak için kriptografi ve şifreleme teknikleri kullandılar. Özellikle internetin yaygınlaşmasından sonra, veri güvenliğinin sağlanması konusunda, kriptografi teknikleri önemli bir rol oynamaktadır.

Web geliştirmede, kriptografi genellikle bir ağ üzerinden aktarılırken veya veritabanlarında saklanırken verilerin güvenliğini sağlamak için kullanılır. Şifreleme işlemlerinin çoğu bir web arka ucunda yürütülür. Bu nedenle, bir Node geliştiricisi olarak, sisteminiz tarafından işlenen verilerin, güvenliğini sağlamak için verilerin nasıl şifreleneceğini ve şifresinin nasıl çözüleceğini anlamalısınız.

Bu makalede, web geliştirmede verilerin güvenliğini sağlamak için kullanılan temel şifreleme tekniklerini inceleyecek ve bunların Node.js ile nasıl uygulanacağını göreceksiniz. Node, bu görevleri kolayca uygulamak için crypto adı verilen yerleşik bir modül sağlar.

İlk adım olarak, kriptografinin (ve şifrelemenin) tam olarak ne olduğunu ve nasıl çalıştığını anlamalıyız.

Kriptografi nedir?

Kriptografi tek bir şey değildir. Verileri güvende tutmak için tekniklerle ilgilenen bütün bir çalışma alanıdır. Kriptografi mantığı şu şekilde izah edilebilir. Öncelikle ilk veri kümesi, doğru kimlik bilgilerine sahip olmayan herkesin anlayamayacağı veya ilk biçimine geri döndüremeyeceği bir hale dönüştürülür.

Bir şifreleme sürecinde üç önemli bileşen vardır: düz metin, şifreli metin ve bir algoritma. Şifreleme algoritması, düz metindeki verileri, karıştırılmış ve tanınmayan bir ilk veri biçimi olan şifreli metne dönüştürür. Algoritma, bu dönüşüm için matematiksel hesaplamalar kullanır.

Genellikle kriptografik algoritmalar, düz metni şifreli metne dönüştürürken anahtar adı verilen bir şey kullanır. Şifreli metni tekrar düz metne dönüştürmek, yalnızca doğru anahtarın olması durumunda mümkündür. Bu nedenle, düz metin görüntüleme ayrıcalığına sahip olanlar, bu anahtarı maksimum güvenlik altında saklamalı ve yabancıların eline geçmesine izin vermemelidir.

Şifreleme nedir?

Şifreleme ve kriptografi bazen birbirinin yerine kullanılsa da, bunlar aynı şey değildir.

Şifreleme, bir algoritma kullanarak düz metni şifreli metne dönüştürme işlemidir. Bu az önce de bahsettiğimiz gibi kriptografinin, sadece bir yönünü oluşturur. Şifrelemenin tersi olan, şifreli metni tekrar düz metne dönüştürme işlemine şifre çözme denir.

Kriptografide, düz metni dönüştürmek için kullanılan bir dizi şifreleme algoritması bulabiliriz.

Kriptografi türleri

Üç temel şifreleme türü vardır: simetrik anahtarlı şifreleme (symmetric-key cryptography), asimetrik anahtarlı şifreleme (asymmetric-key cryptography) ve karma (hashing). Şimdi her birinin ne kadar önemli olduğunu görelim.

Simetrik anahtarlı şifreleme (symmetric-key cryptography)

Bir önceki bölümde, şifreleme algoritmalarının düz metni şifreli metne (veya tam tersi) dönüştürürken anahtarları nasıl kullandığından bahsetmiştik. Simetrik anahtarlı şifrelemede, düz metni şifreli metne dönüştürmek için kullanılan anahtar ile şifreli metni tekrar düz metne dönüştürmek için kullanılan anahtar aynıdır. Bu tür kriptografinin uygulanması kolaydır ve muadili asimetrik anahtar kriptografisinden daha hızlıdır.

Ancak simetrik anahtarlı kriptografinin önemli bir güvenlik sorunu vardır. Bir ağ üzerinden iletilen verileri şifrelerken, bu yöntem hem göndericinin hem de alıcının şifreleme için kullanılan anahtarın ellerinde olmasını gerektirir. Bu, şifreleme anahtarının, üçüncü taraf biri tarafından ele geçirilebileceği anlamına gelir.

Gönderici ve alıcı, şifreleme anahtarını bir ağ üzerinden değiştirmeye çalıştığında, üçüncü bir tarafın anahtarı çalma şansı vardır. Özellikle söz konusu ağ, internet olduğunda, bu risk yüksektir.

Asimetrik anahtarlı şifreleme (asymmetric-key cryptography)

Simetrik anahtarlı şifrelemenin güvenlik endişelerinin üstesinden gelmek için asimetrik anahtarlı şifreleme geliştirildi. Public anahtar ve private anahtar adı verilen bir çift anahtar kullanır. Public anahtar yalnızca verileri şifrelemek için kullanılır. Private anahtar yalnızca verilerin şifresini çözmek için kullanılır. Public anahtarı, onunla şifrelenmiş verilerin şifresini çözmek için kullanamazsınız. Bu aynı şekilde Private anahtar için de geçerlidir.

Bu çift anahtar sisteminin özelliği, açık anahtarın alıcı veya gönderici dışında dış taraflar arasında paylaşılsa bile, sistemin güvenliğini tehlikeye atmamasıdır. Public anahtar şifre çözmede işe yaramadığından, public anahtarın çalınması, şifreli özel kullanıcı verilerini okumak için yeterli olmayacaktır.

Karma (Hashing)

Hashing, yukarıdaki iki kriptografi türünden farklıdır.

Simetrik ve asimetrik şifreleme, düz metnin şifreli metne ve şifreli metnin tekrar düz metne dönüştürülmesini kolaylaştırır. Ancak hashing işleminde yalnızca bir seçeneğiniz vardır: düz metni şifreli metne dönüştürmek. Düz metin "hashing" olduğunda, orijinal içeriği kontrol etmek için onu geri dönüştüremezsiniz.

Bunun yerine yapabileceğiniz şey, iki düz metnin eşit olup olmadığını görmek için başka bir düz metnin aynı hashing değeri oluşturup oluşturmadığını kontrol etmektir. Bu mümkündür, çünkü hashing algoritmalar, her benzersiz düz metnin, benzersiz bir şifreli metin oluşturmasını garantiler.

Hashing genellikle parolaları saklarken kullanılır. Uygulamalar, düz metin parolasını asla veritabanlarında saklamaz. Bunun yerine, parolanın bir hashingini depolarlar. Bir kullanıcının kimliğini doğrularken, bir kullanıcının sağladığı parola tarafından oluşturulan hashingin veritabanında depolanana eşit olup olmadığını kontrol etmeliyiz. Sağlanan parolanın özeti, saklanan hashinge eşitse, sistem kullanıcının kimliğini doğrulayabilir.

Simetrik ve asimetrik kriptografiden farklı olarak, hashing işlemi sırasında bir anahtar kullanmaz.

Node.js ile şifreleme

Node.js, kriptografik işlemleri yürütmek için bazı işlevler sağlayan, yerleşik kripto modülüne sahiptir.

Bu bölümde kripto modülünü kullanarak şifrelemenin nasıl uygulanacağını göreceğiz. Başlamadan önce, her zamanki Node proje ortamınızı kurmanız gerekecek.

Node.js ile verileri şifreleme

Verileri şifrelemek için kripto modülünün Cipher sınıfını kullanabiliriz.

const crypto = require("crypto");

const algorithm = "aes-192-cbc";

const encrypt = (text) => {
  // secret kullanarak şifreleme anahtarı oluşturun
  crypto.scrypt(process.env.SECRET, 'salt', 24, (err, key) => {
    if (err) throw err;

    // bir başlatma vektörü oluştur
    crypto.randomFill(new Uint8Array(16), (err, iv) => {
      if (err) throw err;

      const cipher = crypto.createCipheriv(algorithm, key, iv);

      let encrypted = '';
      cipher.setEncoding('hex');

      cipher.on('data', (chunk) => encrypted += chunk);
      cipher.on('end', () => console.log(encrypted))
      cipher.on('error', (err) => console.log(err))

      cipher.write(text);
      cipher.end();
    });
  });
}

encrypt('hello World');

Crypto modülü ile şifreleme yaparken, şifreleme yöntemi her çağrıldığında yeni bir anahtar oluşturma seçeneğine sahibiz. Şifreleme için farklı anahtarlar kullanmak, saldırganların kaba kuvvet kullanarak verileri deşifre etmesini zorlaştırır.

Ancak bir anahtar oluşturmak için hem şifreleme hem de şifre çözme için ortak bir secret kullanırız. Verilerin şifresini çözen tarafın şifreleme anahtarını oluşturmak için kullanılan secret'a erişimi yoksa, şifre çözme işlemi başarısız olacaktır.

Kullanmış olduğumuz şifreleme algoritması AES ( Advanced Encryption Standard (Gelişmiş Şifreleme Standardı)), 192 bit (24 bayt) algoritmasıdır. Burada 192 bit, anahtarın uzunluğunu gösterir. Anahtar üreten scrypt fonksiyonuna anahtar uzunluğunu 24 olarak nasıl girdiğimizi görebilirsiniz.

Yeni bir şifre nesnesi oluştururken, başlatma vektörü (IV) adı verilen bir parametre iletiyoruz. Genellikle bir şifreleme işleminden geçmeden şifreli metne eklenir. Saldırganların şifrelenmiş verilerdeki kalıpları tanımlayarak verileri deşifre edememeleri için şifreli metinde tekrarlardan kaçınmak için kullanılır. Bu nedenle, IV'ler her zaman öngörülemez ve benzersiz olmalıdır. Bu nedenle, örnekte randomFill işlevini kullanarak yeni bir IV oluşturduk.

Son olarak, yazma işlevi kullanılarak veri şifreleme yaptık. Şifreli veri akışından bir veri yığını mevcut olduğunda ve bu yığın daha sonra şifrelenmiş dizeye eklendiğinde, şifre nesnesi "data" olayını tetikler. “end” olayını tetikleyerek şifrelemenin ne zaman bittiğini tespit edebiliriz. Metni şifrelerken ortaya çıkan hataları tespit etmek için başka bir olay olan “error” kullanıyoruz.

Node.js ile verilerin şifresini çözme

Verilerin şifresini çözmek için kripto modülünün Decipher sınıfını kullanırız. Veri şifrelemenin uygulanma şekline benzer şekilde uygulanır. Secret kullanarak yeni bir şifreleme anahtarı oluşturuyoruz ve ardından şifreyi anahtarla çözmeye başlıyoruz.

const decrypt = (encrypted, iv) => {
  // secret kullanarak şifreleme anahtarı oluştur
  crypto.scrypt(process.env.SECRET, 'salt', 24, (err, key) => {
    if (err) throw err;

    // decipher nesnesi oluştur
    const decipher = crypto.createDecipheriv(algorithm, key, iv);

    let decrypted = '';
    decipher.on('readable', () => {
      while (null !== (chunk = decipher.read())) {
        decrypted += chunk.toString('utf8');
      }
    });
    decipher.on('end', () => console.log(decrypted));
    decipher.on('error', (err) => console.log(err))

    decipher.write(encrypted, 'hex');
    decipher.end();
  })
}

Şifreli metnin şifresini çözmek için, şifreleme işlevindeki verileri şifrelemeye yarayan IV, geçilmelidir.

Node.js ile Hashing

Kripto ile bir hashing işlevi uygulamak oldukça basittir. İşte oluşturduğumuz basit bir hash fonksiyonu.

const hash = text => {

  const hash = crypto.createHash('sha256');

  hash.on('readable', () => {

    const data = hash.read();
    if (data) {
      console.log(data.toString('hex'));
    }
  });

  hash.write(text);
  hash.end();
}

Bu uygulamada, sha256 hashing algoritmasını kullandık. Bu algoritmayı kullanarak, write işlevi ile kolayca bir hashing metin oluşturabilirsiniz. Akışta hashing veri mevcut olduğunda, "readable" olayı tetikler ve hashing dizesini alabiliriz.

Özet

Bu makalede, kriptografi ve veri şifrelemenin temellerini konuşmuş olduk. Ayrıca yerleşik kripto modülü ile Node.js'de kriptografik işlemler uyguladık. Veri şifreleme, web uygulamaları geliştirmek için çok önemli olduğundan, gelecekte daha güvenli uygulamalar oluşturmak için bugün bahsettiklerimizi doğrudan uygulayabilirsiniz. Node'un kripto modülü tarafından desteklenen diğer şifreleme işlemleri türleri hakkında daha fazla bilgi edinmek istiyorsanız, Node'un resmi belgelerini buradan okuyabilirsiniz.

Kriptografi, geniş ve büyüleyici bir çalışma alanıdır. Elbette, bu makalede bahsettiğimizden daha fazla veri koruma yöntemi var. Bu yöntemler hakkında ne kadar çok şey bilirseniz, daha iyi uygulamalar oluşturmak için bir web geliştiricisi olarak size o kadar fayda sağlarlar. Bu yüzden bu gönderiden sonra, şifreleme ve kriptografi tekniklerini öğrenmeyi bırakmayın. Kendi araştırmanızı yapın ve daha fazlasını öğrenin.

Kendinize iyi bakın ve sağlıcakla kalın.

Burası AnatoliaCode.

Anatoliacode Makale Aboneliği

Bize abone olarak tüm makaleleri ilk siz okuyabilirsiniz. Ayrıca asla reklam veya spam yapmıyoruz.