[DEV]AB 1
[DEV]AB
metin2008 1
metin2008
kaptanmikro1 1
kaptanmikro1
Scarlet 1
Scarlet
emirhanHCL 1
emirhanHCL
R 1
Roksam
farkmt2official 1
farkmt2official
TuZaKK 1
TuZaKK
sermin 1
sermin
berkmenoo 1
berkmenoo
Hikaye Ekle

[NODE JS] Crypto ile AES Şifreleme ve Çözme

  • Konuyu başlatan Konuyu başlatan Silverhand
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 1
  • Görüntüleme Görüntüleme 11

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Crypto ile AES Şifreleme ve Çözme​


Bazı veriler sadece hashlenmeyle yetinilemez, geri dönüştürülebilir bir şekilde şifrelenmeleri gerekir. Kullanıcı mesajları, sağlık verileri, finansal bilgiler gibi veriler, depolanırken şifreli olmalı ama ihtiyaç duyulduğunda çözülebilmelidir. İşte bu tür simetrik şifreleme ihtiyaçları için AES (Advanced Encryption Standard) altın standarttır. Node.js'in yerleşik crypto modülü, AES şifrelemeyi kolayca yapmanızı sağlar.

AES üç farklı anahtar uzunluğu destekler: 128-bit, 192-bit ve 256-bit. Anahtar ne kadar uzunsa, şifreleme o kadar güçlüdür. AES-256 askeri düzeyde güvenlik sunar ve günümüz teknolojisiyle kırılması pratik olarak imkânsızdır. Ben projelerimde her zaman AES-256 kullanıyorum, performans farkı neredeyse hissedilmez ama güvenlik çok daha yüksektir.

Şifreleme modları da önemlidir. En yaygın kullanılan modlar CBC (Cipher Block Chaining) ve GCM (Galois/Counter Mode) modlarıdır. CBC modu klasik ve yaygın kullanılan bir moddur ama bütünlük kontrolü sağlamaz. GCM modu ise hem şifreleme hem de bütünlük kontrolü (authentication) sağlar. Bu yüzden modern uygulamalarda GCM modunu tercih etmenizi öneririm. GCM modu, verinin şifreleme sırasında değiştirilip değiştirilmediğini de kontrol eder.

IV (Initialization Vector - Başlatma Vektörü) kavramı kritik öneme sahiptir. IV, aynı anahtar ile aynı veriyi şifrelediğinizde her seferinde farklı sonuç üretilmesini sağlar. Bu, kalıp analizi saldırılarını engeller. IV gizli olması gerekmez ama her şifreleme işleminde benzersiz olmalıdır. Genellikle rastgele üretilir ve şifreli verinin başına eklenir. Çözme sırasında bu IV ayrıştırılıp kullanılır.

Anahtar yönetimi, şifrelemenin en zor kısmıdır. Anahtarınız ne kadar güçlü olursa olsun, düzgün saklanmazsa hiçbir anlamı yoktur. Anahtarları kaynak kodunda veya yapılandırma dosyalarında saklamayın. Ortam değişkenleri, anahtar yönetim servisleri (AWS KMS, HashiCorp Vault gibi) veya donanım güvenlik modülleri (HSM) kullanın.

Pratik bir ipucu: şifrelenmiş veriyi saklarken veya iletirken genellikle Base64 veya Hex kodlaması kullanılır. Bu, binary veriyi güvenli bir şekilde metin formatında saklamanızı sağlar. Ben genellikle Hex tercih ediyorum çünkü Base64'ten biraz daha uzun olsa da debug ederken daha okunabilir.

Bir diğer önemli konu da anahtar türetmedir. Kullanıcıdan alınan bir parola doğrudan şifreleme anahtarı olarak kullanılmamalıdır. Paroladan anahtar türetmek için PBKDF2, scrypt veya Argon2 gibi fonksiyonlar kullanılır. Bu fonksiyonlar, parolayı uygun uzunlukta güçlü bir anahtara dönüştürür.

Performans açısından, AES donanım hızlandırmalı işlemcilerde son derece hızlı çalışır. Modern CPU'ların çoğu AES-NI talimat setini destekler. Node.js'in crypto modülü OpenSSL üzerine kuruludur ve bu donanım hızlandırmadan otomatik olarak yararlanır. Bu yüzden şifreleme işlemleri sanıldığından çok daha hızlıdır.

JavaScript:
// ==============================
// AES-256-GCM Şifreleme ve Çözme
// ==============================
const crypto = require('crypto');

// Şifreleme algoritması ve anahtar uzunluğu
const ALGORITMA = 'aes-256-gcm';
const IV_UZUNLUGU = 16; // 16 byte = 128 bit
const ANAHTAR_UZUNLUGU = 32; // 32 byte = 256 bit
const AUTH_TAG_UZUNLUGU = 16; // 16 byte

// Güvenli anahtar oluşturma
function anahtarOlustur() {
    return crypto.randomBytes(ANAHTAR_UZUNLUGU);
}

// ==============================
// AES-256-GCM ile Şifreleme
// ==============================
function sifrele(duzMetin, anahtar) {
    // Rastgele IV oluştur (her şifreleme için benzersiz olmalı)
    const iv = crypto.randomBytes(IV_UZUNLUGU);

    // Cipher oluştur
    const cipher = crypto.createCipheriv(ALGORITMA, anahtar, iv);

    // Veriyi şifrele
    let sifreliVeri = cipher.update(duzMetin, 'utf8', 'hex');
    sifreliVeri += cipher.final('hex');

    // Authentication tag al (GCM moduna özel)
    const authTag = cipher.getAuthTag();

    // IV + AuthTag + ŞifreliVeri birleştir
    const sonuc = {
        iv: iv.toString('hex'),
        authTag: authTag.toString('hex'),
        sifreliVeri: sifreliVeri,
        // Tek string olarak birleştirilmiş hali
        birlesmis: iv.toString('hex') + ':' + authTag.toString('hex') + ':' + sifreliVeri
    };

    console.log('Şifreleme başarılı!');
    console.log('IV:', sonuc.iv);
    console.log('Auth Tag:', sonuc.authTag);
    console.log('Şifreli veri:', sonuc.sifreliVeri);

    return sonuc;
}

// ==============================
// AES-256-GCM ile Çözme
// ==============================
function coz(birlesmisVeri, anahtar) {
    // Birleştirilmiş veriyi parçala
    const parcalar = birlesmisVeri.split(':');

    if (parcalar.length !== 3) {
        throw new Error('Geçersiz şifreli veri formatı.');
    }

    const iv = Buffer.from(parcalar[0], 'hex');
    const authTag = Buffer.from(parcalar[1], 'hex');
    const sifreliVeri = parcalar[2];

    // Decipher oluştur
    const decipher = crypto.createDecipheriv(ALGORITMA, anahtar, iv);
    decipher.setAuthTag(authTag);

    // Veriyi çöz
    let cozulmusVeri = decipher.update(sifreliVeri, 'hex', 'utf8');
    cozulmusVeri += decipher.final('utf8');

    console.log('Çözme başarılı!');
    console.log('Çözülmüş veri:', cozulmusVeri);

    return cozulmusVeri;
}

// ==============================
// Parola Tabanlı Şifreleme
// ==============================
function parolaIleAnahtarTuret(parola, tuz = null) {
    // Tuz yoksa oluştur
    if (!tuz) {
        tuz = crypto.randomBytes(32);
    }

    // PBKDF2 ile anahtar türet
    const anahtar = crypto.pbkdf2Sync(parola, tuz, 100000, ANAHTAR_UZUNLUGU, 'sha512');

    return { anahtar, tuz };
}

function parolaIleSifrele(duzMetin, parola) {
    const { anahtar, tuz } = parolaIleAnahtarTuret(parola);
    const sifrelenmis = sifrele(duzMetin, anahtar);

    // Tuzu da sonuca ekle
    return tuz.toString('hex') + ':' + sifrelenmis.birlesmis;
}

function parolaIleCoz(birlesmisVeri, parola) {
    const ilkIkiNokta = birlesmisVeri.indexOf(':');
    const tuzHex = birlesmisVeri.substring(0, ilkIkiNokta);
    const kalanVeri = birlesmisVeri.substring(ilkIkiNokta + 1);

    const tuz = Buffer.from(tuzHex, 'hex');
    const { anahtar } = parolaIleAnahtarTuret(parola, tuz);

    return coz(kalanVeri, anahtar);
}

// ==============================
// Dosya Şifreleme
// ==============================
const fs = require('fs');
const { pipeline } = require('stream/promises');

async function dosyaSifrele(kaynakYol, hedefYol, anahtar) {
    const iv = crypto.randomBytes(IV_UZUNLUGU);
    const cipher = crypto.createCipheriv('aes-256-cbc', anahtar, iv);

    // IV'yi dosyanın başına yaz
    const hedefAkis = fs.createWriteStream(hedefYol);
    hedefAkis.write(iv);

    const kaynakAkis = fs.createReadStream(kaynakYol);

    await pipeline(kaynakAkis, cipher, hedefAkis);
    console.log(`Dosya şifrelendi: ${kaynakYol} -> ${hedefYol}`);
}

// ==============================
// Kullanım Örnekleri
// ==============================
console.log('=== AES-256-GCM Şifreleme ===
');

const anahtar = anahtarOlustur();
const gizliBilgi = 'Bu çok gizli bir mesajdır! Türkçe karakterler: şçğüöıİŞÇĞÜÖ';

const sifrelenmis = sifrele(gizliBilgi, anahtar);
console.log('
--- Çözme ---');
const cozulmus = coz(sifrelenmis.birlesmis, anahtar);

console.log('
=== Parola Tabanlı Şifreleme ===
');
const parolaSifrelenmis = parolaIleSifrele('Hassas kullanıcı verisi', 'Güçlü_Parola_123!');
console.log('Şifreli:', parolaSifrelenmis);
const parolaCozulmus = parolaIleCoz(parolaSifrelenmis, 'Güçlü_Parola_123!');
console.log('Çözülmüş:', parolaCozulmus);

AES şifreleme, hassas verileri korumak için vazgeçilmez bir araçtır. GCM modunu tercih edin, IV'leri her zaman rastgele oluşturun ve anahtarlarınızı güvenli bir şekilde saklayın. Parola tabanlı şifrelemede PBKDF2 veya scrypt ile anahtar türetmeyi unutmayın. Şifreleme kolay görünebilir ama küçük hatalar büyük güvenlik açıklarına yol açabilir.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst