- Αρχική
- Τεκμηρίωση Κρυπτογράφησης
Τεκμηρίωση Κρυπτογράφησης
Μάθετε πώς λειτουργεί η κρυπτογράφηση AES-256-GCM. Πλήρης τεκμηρίωση με παραδείγματα κώδικα για την υλοποίηση κρυπτογράφησης από την πλευρά του πελάτη.
Κεφάλαια
Πώς λειτουργεί
Παραγωγή Κλειδιού
Ο κωδικός πρόσβασής σας χρησιμοποιείται για την παραγωγή ενός κλειδιού AES 256-bit χρησιμοποιώντας PBKDF2 με SHA-256 και 600.000 επαναλήψεις. Αυτό καθιστά τις επιθέσεις brute-force υπολογιστικά δαπανηρές.
Τυχαίες Τιμές
Ένα τυχαίο salt 128-bit και ένα IV (Διάνυσμα Αρχικοποίησης) 96-bit παράγονται χρησιμοποιώντας κρυπτογραφικά ασφαλή παραγωγή τυχαίων αριθμών για κάθε κρυπτογράφηση.
Κρυπτογράφηση AES-256-GCM
Τα δεδομένα κρυπτογραφούνται χρησιμοποιώντας AES-256-GCM (Galois/Counter Mode), το οποίο παρέχει τόσο εμπιστευτικότητα όσο και επαλήθευση αυθεντικότητας.
Μορφή Εξόδου
Η έξοδος μορφοποιείται ως v1:salt:iv:ciphertext όπου όλα τα στοιχεία είναι κωδικοποιημένα σε base64.
Συναρτήσεις κρυπτογράφησης
Παραγωγή Κλειδιού
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']
);
}
Βοηθητικά
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;
}
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(':');
}
Αποκρυπτογράφηση
/**
* 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);
}
Πλήρες Παράδειγμα
/**
* 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);
})();
Αναμενόμενη Έξοδος
Αρχικό: Hello World Κρυπτογραφημένο: v1:aBcDeFgHiJkLmNoP...:qRsTuVwXyZ...:encrypted_data... Αποκρυπτογραφημένο: Hello World
Σημείωση: Η κρυπτογραφημένη έξοδος θα είναι διαφορετική κάθε φορά λόγω της τυχαίας παραγωγής salt και IV, αλλά η αποκρυπτογράφηση θα επιστρέφει πάντα το αρχικό μήνυμα.
Είστε έτοιμοι να το δοκιμάσετε;
Χρησιμοποιήστε το διαδραστικό εργαλείο κρυπτογράφησης για να δείτε αυτή την κρυπτογράφηση σε δράση.
Δοκιμάστε το Εργαλείο Κρυπτογράφησης