Şifreleme Dokümantasyonu

AES-256-GCM şifrelememizin nasıl çalıştığını öğrenin. İstemci tarafı şifrelemeyi uygulamak için kod örnekleri içeren tam dokümantasyon.

Nasıl çalışır

Anahtar Türetme

Parolanız, SHA-256 ve 600.000 yineleme ile PBKDF2 kullanılarak 256 bitlik bir AES anahtarı türetmek için kullanılır. Bu, kaba kuvvet saldırılarını hesaplama açısından pahalı hale getirir.

Rastgele Değerler

Her şifreleme için kriptografik olarak güvenli rastgele sayı üretimi kullanılarak rastgele bir 128 bitlik tuz ve 96 bitlik IV (Başlatma Vektörü) oluşturulur.

AES-256-GCM Şifreleme

Veriler, hem gizlilik hem de orijinallik doğrulaması sağlayan AES-256-GCM (Galois/Counter Mode) kullanılarak şifrelenir.

Çıktı Formatı

Çıktı, tüm bileşenlerin base64 kodlu olduğu v1:salt:iv:ciphertext olarak biçimlendirilir.

Şifreleme İşlevleri

Anahtar Türet

Paroladan AES anahtarı türet
Paroladan 256 bitlik bir AES-GCM anahtarı türetmek için SHA-256 ve 600.000 yineleme ile PBKDF2 kullanır.
async function deriveAesGcmKey(password, saltBytes) {
    const te = new TextEncoder();
    const baseKey = await crypto.subtle.importKey(
        'raw',
        te.encode(password),
        { name: 'PBKDF2' },
        false,
        ['deriveKey']
    );

    return crypto.subtle.deriveKey(
        {
            name: 'PBKDF2',
            hash: 'SHA-256',
            salt: saltBytes,
            iterations: 600000, // OWASP 2025 recommended minimum
        },
        baseKey,
        { name: 'AES-GCM', length: 256 },
        false,
        ['encrypt', 'decrypt']
    );
}

Yardımcılar

Yardımcı fonksiyonlar
Bayt dizileri için Base64 kodlama ve kod çözme yardımcı programları.
function bytesToBase64(bytes) {
    let binary = '';
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return btoa(binary);
}

function base64ToBytes(base64) {
    const binary = atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
        bytes[i] = binary.charCodeAt(i);
    }
    return bytes;
}

Şifrele

Verileri şifrele
Rastgele bir tuz ve IV ile AES-256-GCM kullanarak düz metni şifreler. Biçimlendirilmiş yükü döndürür.
/**
 * Build combined key from password and salt key
 * Format: "password:saltKey"
 */
function buildCombinedKey(password, saltKey) {
    if (saltKey) {
        return password + ':' + saltKey;
    }
    return password;
}

async function encrypt(plainText, password, saltKey = '') {
    const te = new TextEncoder();
    const salt = crypto.getRandomValues(new Uint8Array(16));
    const iv = crypto.getRandomValues(new Uint8Array(12));
    const combinedKey = buildCombinedKey(password, saltKey);
    const key = await deriveAesGcmKey(combinedKey, salt);

    const cipherBuf = await crypto.subtle.encrypt(
        { name: 'AES-GCM', iv },
        key,
        te.encode(plainText)
    );

    return [
        'v1',
        bytesToBase64(salt),
        bytesToBase64(iv),
        bytesToBase64(new Uint8Array(cipherBuf)),
    ].join(':');
}

Şifreyi Çöz

Verilerin şifresini çöz
Orijinal parolayı kullanarak bir v1 yükünü tekrar düz metne çözer.
/**
 * Build combined key from password and salt key
 * Format: "password:saltKey"
 */
function buildCombinedKey(password, saltKey) {
    if (saltKey) {
        return password + ':' + saltKey;
    }
    return password;
}

async function decrypt(payload, password, saltKey = '') {
    const td = new TextDecoder();
    const [version, saltB64, ivB64, cipherB64] = payload.split(':');

    if (version !== 'v1') {
        throw new Error('Unsupported payload version');
    }

    const salt = base64ToBytes(saltB64);
    const iv = base64ToBytes(ivB64);
    const ciphertext = base64ToBytes(cipherB64);
    const combinedKey = buildCombinedKey(password, saltKey);
    const key = await deriveAesGcmKey(combinedKey, salt);

    const plainBuf = await crypto.subtle.decrypt(
        { name: 'AES-GCM', iv },
        key,
        ciphertext
    );

    return td.decode(plainBuf);
}

Tam Örnek

Kullanıma hazır kod
Bu tam örneği tarayıcı konsolunuza veya JavaScript dosyanıza kopyalayıp yapıştırın.
/**
 * AES-256-GCM Encryption/Decryption Example
 * Encrypts "Hello World" and decrypts it back
 */

// Salt key (RK) - used to strengthen password-based encryption
const SALT_KEY = '9x=1KO2tUFw#G:ARZd>Ff)s(^H+DWY4MpgJ:Cp_pCUU|og$>6a.bS.;ij9Wnw';

// Helper functions
function bytesToBase64(bytes) {
    let binary = '';
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return btoa(binary);
}

function base64ToBytes(base64) {
    const binary = atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
        bytes[i] = binary.charCodeAt(i);
    }
    return bytes;
}

/**
 * Build combined key from password and salt key
 * Format: "password:saltKey"
 */
function buildCombinedKey(password, saltKey) {
    if (saltKey) {
        return password + ':' + saltKey;
    }
    return password;
}

/**
 * Version configuration for encryption payloads
 * v1: 150,000 iterations (legacy)
 * v2: 600,000 iterations (current, OWASP 2025 recommended)
 */
const VERSION_CONFIG = {
    v1: { iterations: 150000 },
    v2: { iterations: 600000 },
};
const CURRENT_VERSION = 'v2';

// Derive AES-256 key from password using PBKDF2
async function deriveAesGcmKey(password, saltBytes, iterations) {
    const te = new TextEncoder();
    const baseKey = await crypto.subtle.importKey(
        'raw',
        te.encode(password),
        { name: 'PBKDF2' },
        false,
        ['deriveKey']
    );

    return crypto.subtle.deriveKey(
        {
            name: 'PBKDF2',
            hash: 'SHA-256',
            salt: saltBytes,
            iterations: iterations,
        },
        baseKey,
        { name: 'AES-GCM', length: 256 },
        false,
        ['encrypt', 'decrypt']
    );
}

// Encrypt function (uses v2 with 600,000 iterations)
async function encrypt(plainText, password, saltKey = '') {
    const te = new TextEncoder();
    const salt = crypto.getRandomValues(new Uint8Array(16));
    const iv = crypto.getRandomValues(new Uint8Array(12));
    const combinedKey = buildCombinedKey(password, saltKey);
    const iterations = VERSION_CONFIG[CURRENT_VERSION].iterations;
    const key = await deriveAesGcmKey(combinedKey, salt, iterations);

    const cipherBuf = await crypto.subtle.encrypt(
        { name: 'AES-GCM', iv },
        key,
        te.encode(plainText)
    );

    return [
        CURRENT_VERSION,
        bytesToBase64(salt),
        bytesToBase64(iv),
        bytesToBase64(new Uint8Array(cipherBuf)),
    ].join(':');
}

// Decrypt function (supports both v1 and v2)
async function decrypt(payload, password, saltKey = '') {
    const td = new TextDecoder();
    const [version, saltB64, ivB64, cipherB64] = payload.split(':');

    const versionConfig = VERSION_CONFIG[version];
    if (!versionConfig) {
        throw new Error('Unsupported payload version: ' + version);
    }

    const salt = base64ToBytes(saltB64);
    const iv = base64ToBytes(ivB64);
    const ciphertext = base64ToBytes(cipherB64);
    const combinedKey = buildCombinedKey(password, saltKey);
    const key = await deriveAesGcmKey(combinedKey, salt, versionConfig.iterations);

    const plainBuf = await crypto.subtle.decrypt(
        { name: 'AES-GCM', iv },
        key,
        ciphertext
    );

    return td.decode(plainBuf);
}

// Example usage
(async () => {
    const message = 'Hello World';
    const password = 'my-secret-password';

    console.log('Original:', message);

    // Encrypt with salt key (uses v2)
    const encrypted = await encrypt(message, password, SALT_KEY);
    console.log('Encrypted:', encrypted);

    // Decrypt with same salt key (supports v1 and v2)
    const decrypted = await decrypt(encrypted, password, SALT_KEY);
    console.log('Decrypted:', decrypted);
})();

Beklenen Çıktı

Beklenen konsol çıktısı
Orijinal: Hello World
Şifreli: v1:aBcDeFgHiJkLmNoP...:qRsTuVwXyZ...:encrypted_data...
Şifresi Çözülmüş: Hello World

Not: Şifreli çıktı, rastgele tuz ve IV üretimi nedeniyle her seferinde farklı olacaktır, ancak şifre çözme her zaman orijinal mesajı döndürecektir.

Denemeye hazır mısınız?

Bu şifrelemeyi çalışırken görmek için etkileşimli şifreleme aracımızı kullanın.

Şifreleme Aracını Dene

Neredeyse hiç çerez kullanmıyoruz

Sadece web sitesinin güvenliğini artıran ve kullanıcı deneyiminizi geliştiren kesinlikle gerekli çerezleri kullanıyoruz. Davranışınızı veya etkinliğinizi takip etmiyoruz.