ECDH ma’lumotnomasi
ECDH obyekti
ECDH (Elliptic Curve Diffie-Hellman) klassi Node.js crypto modulining bir qismidir. U Elliptic Curve Diffie-Hellman kalit almashish protokolini amalga oshiradi, bu ikki tomonga elliptik egri chiziq kriptografiyasidan foydalangan holda xavfsiz bo‘lmagan kanal orqali umumiy sirni xavfsiz o‘rnatish imkonini beradi.
ECDH an’anaviy Diffie-Hellman kalit almashinuviga nisbatan afzalliklarni taklif etadi, jumladan kichikroq kalit o‘lchamlari, tezroq hisoblash va ekvivalent xavfsizlik kuchi.
Kripto modulini import qilish
// Import the crypto module
const crypto = require('crypto');
// Create an ECDH instance with a specific curve
const ecdh = crypto.createECDH('prime256v1'); // Also known as P-256 or secp256r1
Misolni ishga tushirish »
ECDH usullari
| Metod | Tavsif |
|---|---|
| ecdh.generateKeys([encoding[, format]]) | Shaxsiy va ommaviy EC Diffie-Hellman kalit qiymatlarini yaratadi. Agar encoding berilsa, string qaytariladi; aks holda buffer qaytariladi. format argumenti nuqta kodlashni belgilaydi va "siqilgan", "siqilmagan" yoki "gibrid" bo‘lishi mumkin. |
| ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding]) | Boshqa tomonning ochiq kaliti yordamida umumiy sirni hisoblaydi. Agar inputEncoding berilgan bo‘lsa, otherPublicKey string bo‘lishi kutiladi; aks holda, Buffer, TypedArray yoki DataView. Agar outputEncoding berilsa, string qaytariladi; aks holda buffer qaytariladi. |
| ecdh.getPrivateKey([encoding]) | EC Diffie-Hellman shaxsiy kalitini qaytaradi. Agar encoding berilsa, string qaytariladi; aks holda buffer qaytariladi. |
| ecdh.getPublicKey([encoding][, format]) | EC Diffie-Hellman ochiq kalitini qaytaradi. Agar encoding berilsa, string qaytariladi; aks holda buffer qaytariladi. format argumenti nuqta kodlashni belgilaydi va "siqilgan", "siqilmagan" yoki "gibrid" bo‘lishi mumkin. |
| ecdh.setPrivateKey(privateKey[, encoding]) | EC Diffie-Hellman shaxsiy kalitini o‘rnatadi. Agar encoding berilgan bo‘lsa, privateKey string bo‘lishi kutiladi; aks holda, Buffer, TypedArray yoki DataView. |
Qo‘llab-quvvatlanadigan egri chiziqlar
Node.js ECDH uchun turli elliptik egri chiziqlarni qo‘llab-quvvatlaydi. Siz barcha qo‘llab-quvvatlanadigan egri chiziqlar ro‘yxatini olishingiz mumkin:
const crypto = require('crypto');
// Get all supported elliptic curves
console.log(crypto.getCurves());
Misolni ishga tushirish »
ECDH uchun umumiy egri chiziqlarga quyidagilar kiradi:
| Egri chiziq nomi | Muqobil ismlar | Hajmi | Xavfsizlik darajasi |
|---|---|---|---|
| prime256v1 | P-256, secp256r1 | 256 bit | 128 bit |
| secp384r1 | P-384 | 384 bit | 192 bit |
| secp521r1 | P-521 | 521 bit | 256 bit |
| secp256k1 | (Bitcoin curve) | 256 bit | 128 bit |
| ed25519 | egri 25519 | 255 bit | 128 bit |
Asosiy kalit almashinuvi misoli
Quyidagi misol ikki tomon (Elis va Bob) o‘rtasidagi asosiy ECDH kalit almashinuvini ko‘rsatadi:
const crypto = require('crypto');
// Alice creates an ECDH instance and generates keys
console.log('Alice: Creating ECDH instance...');
const alice = crypto.createECDH('prime256v1');
alice.generateKeys();
// Bob creates an ECDH instance and generates keys
console.log('Bob: Creating ECDH instance...');
const bob = crypto.createECDH('prime256v1');
bob.generateKeys();
// Exchange public keys (over an insecure channel)
console.log('Exchanging public keys...');
const alicePublicKey = alice.getPublicKey();
const bobPublicKey = bob.getPublicKey();
// Alice computes the shared secret using Bob's public key
console.log('Alice: Computing shared secret...');
const aliceSecret = alice.computeSecret(bobPublicKey);
// Bob computes the shared secret using Alice's public key
console.log('Bob: Computing shared secret...');
const bobSecret = bob.computeSecret(alicePublicKey);
// Both secrets should be the same
console.log('Alice\'s secret:', aliceSecret.toString('hex'));
console.log('Bob\'s secret:', bobSecret.toString('hex'));
console.log('Do they match?', aliceSecret.equals(bobSecret));
// This shared secret can now be used as a key for symmetric encryption
Misolni ishga tushirish »
Turli kodlash formatlari bilan ECDH
ECDH turli xil ochiq kalit kodlash formatlarini qo‘llab-quvvatlaydi:
const crypto = require('crypto');
// Create an ECDH instance
const ecdh = crypto.createECDH('prime256v1');
ecdh.generateKeys();
// Get public key in different formats
const uncompressedKey = ecdh.getPublicKey('hex', 'uncompressed');
const compressedKey = ecdh.getPublicKey('hex', 'compressed');
const hybridKey = ecdh.getPublicKey('hex', 'hybrid');
console.log('Uncompressed public key:', uncompressedKey);
console.log('Compressed public key:', compressedKey);
console.log('Hybrid public key:', hybridKey);
// Get key length in each format
console.log('\nKey lengths:');
console.log('Uncompressed:', Buffer.from(uncompressedKey, 'hex').length, 'bytes');
console.log('Compressed:', Buffer.from(compressedKey, 'hex').length, 'bytes');
console.log('Hybrid:', Buffer.from(hybridKey, 'hex').length, 'bytes');
// Use a public key in different formats
const otherEcdh = crypto.createECDH('prime256v1');
otherEcdh.generateKeys();
// Another party can use any format to compute the same secret
const secret1 = otherEcdh.computeSecret(
Buffer.from(uncompressedKey, 'hex')
);
const secret2 = otherEcdh.computeSecret(
Buffer.from(compressedKey, 'hex')
);
console.log('\nSame secret computed from different formats?',
secret1.equals(secret2));
Misolni ishga tushirish »
Shifrlash bilan ECDH
Ushbu misol AES shifrlash uchun umumiy kalitni yaratish uchun ECDH dan foydalanishning to‘liq stsenariysini ko‘rsatadi:
const crypto = require('crypto');
// Create ECDH instances for Alice and Bob
const alice = crypto.createECDH('prime256v1');
alice.generateKeys();
const bob = crypto.createECDH('prime256v1');
bob.generateKeys();
// Exchange public keys
const alicePublicKey = alice.getPublicKey();
const bobPublicKey = bob.getPublicKey();
// Compute shared secrets
const aliceSecret = alice.computeSecret(bobPublicKey);
const bobSecret = bob.computeSecret(alicePublicKey);
// Use the shared secret as a key for encryption
// First, derive a suitable key using a hash function
function deriveKey(secret, salt, keyLength) {
return crypto.pbkdf2Sync(secret, salt, 1000, keyLength, 'sha256');
}
// Alice sends an encrypted message to Bob
function encrypt(text, secret) {
// Create a salt and derive a key
const salt = crypto.randomBytes(16);
const key = deriveKey(secret, salt, 32); // 32 bytes for AES-256
const iv = crypto.randomBytes(16);
// Encrypt the message
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
// Return everything Bob needs to decrypt
return {
salt: salt.toString('hex'),
iv: iv.toString('hex'),
encrypted
};
}
// Bob decrypts the message from Alice
function decrypt(encryptedInfo, secret) {
// Parse values
const salt = Buffer.from(encryptedInfo.salt, 'hex');
const iv = Buffer.from(encryptedInfo.iv, 'hex');
const encrypted = encryptedInfo.encrypted;
// Derive the same key
const key = deriveKey(secret, salt, 32);
// Decrypt the message
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// Alice encrypts a message using the shared secret
const message = 'Hello Bob, this is a secret message from Alice using ECDH!';
console.log('Original message:', message);
const encryptedMessage = encrypt(message, aliceSecret);
console.log('Encrypted message:', encryptedMessage);
// Bob decrypts the message using his shared secret
const decryptedMessage = decrypt(encryptedMessage, bobSecret);
console.log('Decrypted message:', decryptedMessage);
// Verify the result
console.log('Decryption successful:', message === decryptedMessage);
Misolni ishga tushirish »
Shaxsiy kalitni qo‘lda sozlash
Shaxsiy kalitni yaratish o‘rniga qo‘lda o‘rnatishingiz mumkin:
const crypto = require('crypto');
// Create an ECDH instance
const ecdh = crypto.createECDH('prime256v1');
// Generate a random private key (32 bytes for prime256v1)
const privateKey = crypto.randomBytes(32);
console.log('Private key (hex):', privateKey.toString('hex'));
// Set the private key
ecdh.setPrivateKey(privateKey);
// Derive the public key from the private key
const publicKey = ecdh.getPublicKey('hex', 'uncompressed');
console.log('Public key (hex):', publicKey);
// You can also set the private key from a hex string
const ecdh2 = crypto.createECDH('prime256v1');
ecdh2.setPrivateKey(privateKey.toString('hex'), 'hex');
// Check if both instances generate the same public key
const publicKey2 = ecdh2.getPublicKey('hex', 'uncompressed');
console.log('Same public keys:', publicKey === publicKey2);
// This is useful for deterministic key generation or when loading keys from storage
Misolni ishga tushirish »
Turli egri chiziqlar bilan ECDH
Ushbu misol ECDH bilan turli elliptik egri chiziqlardan qanday foydalanishni ko‘rsatadi:
const crypto = require('crypto');
// Function to perform ECDH key exchange with a specific curve
function testCurve(curveName) {
console.log(`\nTesting curve: ${curveName}`);
try {
// Create ECDH instances
const alice = crypto.createECDH(curveName);
alice.generateKeys();
const bob = crypto.createECDH(curveName);
bob.generateKeys();
// Exchange public keys
const alicePublicKey = alice.getPublicKey();
const bobPublicKey = bob.getPublicKey();
// Compute shared secrets
const aliceSecret = alice.computeSecret(bobPublicKey);
const bobSecret = bob.computeSecret(alicePublicKey);
// Check if secrets match
const match = aliceSecret.equals(bobSecret);
// Output results
console.log(`Public key size: ${alicePublicKey.length} bytes`);
console.log(`Shared secret size: ${aliceSecret.length} bytes`);
console.log(`Secrets match: ${match}`);
return match;
} catch (error) {
console.error(`Error with curve ${curveName}: ${error.message}`);
return false;
}
}
// Test different curves
const curves = [
'prime256v1', // P-256 / secp256r1
'secp384r1', // P-384
'secp521r1', // P-521
'secp256k1', // Bitcoin curve
'curve25519' // Ed25519 curve (if supported)
];
curves.forEach(curve => {
testCurve(curve);
});
// Note: Not all curves may be supported in your Node.js version
Misolni ishga tushirish »
Samaradorlikni taqqoslash
Ushbu misol ECDH samaradorligini an’anaviy Diffie-Hellman bilan taqqoslaydi:
const crypto = require('crypto');
const { performance } = require('perf_hooks');
// Function to measure DH key generation time
function measureDH(bits) {
const startTime = performance.now();
const dh = crypto.createDiffieHellman(bits);
dh.generateKeys();
const endTime = performance.now();
return endTime - startTime;
}
// Function to measure ECDH key generation time
function measureECDH(curve) {
const startTime = performance.now();
const ecdh = crypto.createECDH(curve);
ecdh.generateKeys();
const endTime = performance.now();
return endTime - startTime;
}
// Function to measure secret computation time
function measureSecretComputation(type, params) {
let alice, bob;
// Create instances and generate keys
if (type === 'DH') {
alice = crypto.createDiffieHellman(params);
alice.generateKeys();
bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
bob.generateKeys();
} else {
alice = crypto.createECDH(params);
alice.generateKeys();
bob = crypto.createECDH(params);
bob.generateKeys();
}
// Exchange public keys
const alicePublicKey = alice.getPublicKey();
const bobPublicKey = bob.getPublicKey();
// Measure time for computing secrets
const startTime = performance.now();
alice.computeSecret(bobPublicKey);
bob.computeSecret(alicePublicKey);
const endTime = performance.now();
return endTime - startTime;
}
// Run performance tests
console.log('Key Generation Performance:');
console.log(`DH (1024 bits): ${measureDH(1024).toFixed(2)} ms`);
console.log(`DH (2048 bits): ${measureDH(2048).toFixed(2)} ms`);
console.log(`ECDH (P-256): ${measureECDH('prime256v1').toFixed(2)} ms`);
console.log(`ECDH (P-384): ${measureECDH('secp384r1').toFixed(2)} ms`);
console.log(`ECDH (P-521): ${measureECDH('secp521r1').toFixed(2)} ms`);
console.log('\nSecret Computation Performance:');
console.log(`DH (1024 bits): ${measureSecretComputation('DH', 1024).toFixed(2)} ms`);
console.log(`DH (2048 bits): ${measureSecretComputation('DH', 2048).toFixed(2)} ms`);
console.log(`ECDH (P-256): ${measureSecretComputation('ECDH', 'prime256v1').toFixed(2)} ms`);
console.log(`ECDH (P-384): ${measureSecretComputation('ECDH', 'secp384r1').toFixed(2)} ms`);
console.log(`ECDH (P-521): ${measureSecretComputation('ECDH', 'secp521r1').toFixed(2)} ms`);
Misolni ishga tushirish »
TLS uchun ECDH kalit juftligini yaratish
Ushbu misol TLS bilan foydalanish uchun ECDH kalit juftlarini qanday yaratishni ko‘rsatadi:
const crypto = require('crypto');
const fs = require('fs');
// Function to generate and save ECDH keys for TLS
function generateEcdhKeysForTLS(curveName, keyFilePrefix) {
// Create ECDH instance
const ecdh = crypto.createECDH(curveName);
// Generate keys
ecdh.generateKeys();
// Get keys in PEM format
const privateKey = ecdh.getPrivateKey('hex');
const publicKey = ecdh.getPublicKey('hex', 'uncompressed');
// Save keys to files
fs.writeFileSync(`${keyFilePrefix}_private.hex`, privateKey);
fs.writeFileSync(`${keyFilePrefix}_public.hex`, publicKey);
console.log(`Generated ECDH key pair using ${curveName}`);
console.log(`Private key saved to ${keyFilePrefix}_private.hex`);
console.log(`Public key saved to ${keyFilePrefix}_public.hex`);
return {
curve: curveName,
privateKey,
publicKey
};
}
// Generate keys for different curves
generateEcdhKeysForTLS('prime256v1', 'ecdh_p256');
generateEcdhKeysForTLS('secp384r1', 'ecdh_p384');
console.log("\nThese keys can be used for ECDHE (Ephemeral ECDH) in TLS connections.");
console.log("In a real application, you would use these with the TLS module or a library like Node.js's tls module.");
Misolni ishga tushirish »
Xavfsizlik masalalari
ECDH kalit almashinuvidan foydalanganda, xavfsizlikning eng yaxshi amaliyotlarini ko‘rib chiqing:
- Tegishli egri chiziqlarni tanlang: Ko‘pgina ilovalar uchun P-256 (prime256v1) xavfsizlik va ishlashning yaxshi muvozanatini ta’minlaydi. Yuqori xavfsizlik talablari uchun P-384 yoki P-521 ni ko‘rib chiqing.
- Zaif yoki eskirgan egri chiziqlardan saqlaning: Ba’zi egri chiziqlarning zaif tomonlari borligi ma’lum. Har doim xavfsizlik organlari tomonidan tavsiya etilgan standart egri chiziqlardan foydalaning.
- Efemer kalitlardan foydalaning: Har bir seans uchun yangi ECDH kalit juftlarini yarating.
- Autentifikatsiyani qo‘shish: Sof ECDH (masalan, DH) o‘rtadagi odam hujumlariga nisbatan zaifdir. Raqamli imzolar bilan ECDHE kabi autentifikatsiya qilingan kalit almashish protokollaridan foydalanishni o‘ylab ko‘ring.
- Shaxsiy kalitlarni himoya qiling: Hech qachon shaxsiy kalitlarni jurnallarda, debug chiqishida yoki mijoz kodida ko‘rsatmang.
- Shifrlash kalitlarini to‘g‘ri oling: Umumiy sirdan bevosita shifrlash kaliti sifatida foydalanmang. HKDF yoki PBKDF2 kabi kalit hosil qilish funksiyasidan (KDF) foydalaning.
- Ochiq kalitlarni tekshirish: Yaroqsiz egri chiziq hujumlarini oldini olish uchun qabul qilingan ochiq kalitlarning elliptik egri chiziqdagi haqiqiy nuqtalar ekanligini tasdiqlang.
DH va ECDH ni solishtirish
Ushbu jadval an’anaviy Diffie-Hellmanni elliptik egri chiziqli Diffie-Hellman bilan taqqoslaydi:
| Xususiyat | Diffie-Hellman | ECDH |
|---|---|---|
| Kalit hajmi | Odatda 2048-4096 bit | Odatda 256-384 bit |
| Ishlash | Sekinroq, ko‘proq hisoblashni talab qiladi | Tezroq, samaraliroq |
| Xavfsizlik darajasi | 2048-bitli DH ≈ 112-bitli xavfsizlik | 256-bitli ECDH ≈ 128-bitli xavfsizlik |
| Xotiradan foydalanish | Yuqori | Pastroq |
| Zamonaviy foydalanish | Yangi dizaynlarda kamroq tarqalgan | Yangi protokollarda ko‘proq uchraydi (TLS 1.3 va boshqalar) |
| Amalga oshirish | Oddiyroq matematika | Yana murakkab elliptik egri operatsiyalar |
Ko‘pgina zamonaviy ilovalar uchun ECDH yaxshi ishlashi va kichikroq kalit o‘lchamlari tufayli ekvivalent yoki yaxshi xavfsizlikni ta’minlaydi.
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
