تشفير WebAssembly: سرعة تشفير شبه أصلية في المتصفح
استخدم WebAssembly لتحقيق سرعات تشفير شبه أصلية. قارن تنفيذات WASM crypto.
تعمل مكتبات التشفير المُصرَّفة لـ WASM بنحو 60-80% من سرعة C الأصلية في المتصفح، وهو ما يعني 3-10 أضعاف سرعة تنفيذات JavaScript الخالصة. للمكوّنات التشفيرية الغائبة من Web Crypto API (ChaCha20-Poly1305، وArgon2id، وXChaCha20، وآليات تغليف المفاتيح ما بعد الكمية مثل Kyber)، يُعدّ WASM المسار العملي نحو أداء مقبول. libsodium.js هو الخيار السائد، إذ يوفّر واجهة libsodium الكاملة بثنائي WASM بحجم 200 كيلوبايت. أما للمكوّنات التي تدعمها Web Crypto أصلاً كـ AES-256-GCM، فإن التنفيذ الأصلي المُسرَّع عتادياً في المتصفح يتفوق على WASM بوضوح، لذا لا يكون WASM دائماً الأداة المناسبة. يتناول هذا الدليل متى تلجأ إليه وكيف تُقيّم المقايضات.
متى تتفوق Web Crypto الأصلية
للخوارزميات التي تعرضها Web Crypto أصلاً — AES-GCM وAES-CBC وAES-CTR وPBKDF2 وHMAC وRSA-OAEP وECDH وECDSA وSHA-256/384/512 — يستخدم التنفيذ الأصلي في المتصفح التسريع العتادي عبر AES-NI على x86 وامتدادات تشفير ARMv8 على الأجهزة المحمولة. الإنتاجية النموذجية لـ AES-256-GCM:
- Web Crypto (Chrome على Apple Silicon): 1.7 جيجابايت/ثانية
- Web Crypto (Chrome على Intel x86 مع AES-NI): 1.2 جيجابايت/ثانية
- libsodium WASM AES-GCM: 400-800 ميجابايت/ثانية
- OpenSSL مرجعي أصلي: 3-5 جيجابايت/ثانية
لا يملك WASM وصولاً إلى AES-NI من داخل الصندوق المعزول؛ فيُعود إلى تنفيذات AES ذات الشرائح المتعددة (bitsliced) وهي أبطأ لكنها ثابتة الوقت. لكل ما تدعمه Web Crypto، استخدمها أولاً.
أين يتفوق WASM
للخوارزميات الغائبة من Web Crypto:
- ChaCha20-Poly1305: أسرع من AES على الأجهزة التي تفتقر إلى AES-NI. لا دعم أصلي في المتصفح حتى 2026.
- XChaCha20-Poly1305: nonces ذات 192 بتاً تجعل استخدام nonces عشوائية آمناً في أي مقياس.
- Argon2id: دالة تجزئة كلمات المرور الفائزة بـ PHC. لا دعم أصلي في المتصفح.
- X25519 / Ed25519: أضاف Safari 17 وFirefox 129 دعماً أصلياً، لكن WASM لا يزال المسار المحمول.
- BLAKE2b / BLAKE3: دوال تجزئة سريعة غير موجودة في Web Crypto.
- Kyber وDilithium وSPHINCS+: مكوّنات ما بعد الكم؛ مجال المكتبات فقط.
- Streaming AEAD: تعالج
crypto_secretstreamفي libsodium تشفير الملفات الكبيرة بشكل متدفق بنظافة؛ لا ما يعادلها في Web Crypto.
تنفيذات JavaScript موجودة لهذه الخوارزميات لكنها أبطأ بـ 5-20 مرة من WASM. على ملف بحجم 1 جيجابايت مع ChaCha20-Poly1305، يعمل WASM في ~ثانيتين بينما تستغرق JS الخالصة 15-40 ثانية.
libsodium.js: العمود الفقري
libsodium-wrappers (مبنية على Emscripten مع غلافات JS) هي المكتبة الأساسية. 200 كيلوبايت WASM + ~50 كيلوبايت غلاف JS، مضغوطة.
import _sodium from 'libsodium-wrappers';
await _sodium.ready;
const sodium = _sodium;
// تشفير موثق بـ ChaCha20-Poly1305
const key = sodium.crypto_aead_xchacha20poly1305_ietf_keygen();
const nonce = sodium.randombytes_buf(sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
const ciphertext = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
plaintext, null, null, nonce, key
);
البناء "sumo" (يتضمن خوارزميات أكثر) بحجم ~600 كيلوبايت؛ البناء الافتراضي يغطي 90% من حالات الاستخدام بما فيها AEAD وتجزئة كلمات المرور (Argon2id) وX25519 وEd25519.
حمّل بشكل ديناميكي حتى لا يعيق ثنائي WASM عرض الصفحة الأولي:
async function getSodium() {
if (!window._sodium) {
const mod = await import('libsodium-wrappers');
await mod.ready;
window._sodium = mod;
}
return window._sodium;
}
Streaming AEAD عبر crypto_secretstream
لنقل الملفات الكبيرة، تُعدّ crypto_secretstream_xchacha20poly1305 في libsodium أنظف streaming AEAD متاحة في المتصفح:
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
const chunk1 = sodium.crypto_secretstream_xchacha20poly1305_push(
state, plaintext1, null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
);
// الجزء الأخير يستخدم TAG_FINAL حتى يكتشف المستقبل البتر
const chunkLast = sodium.crypto_secretstream_xchacha20poly1305_push(
state, plaintextLast, null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
);
يُمكِّن علامة TAG_FINAL المستقبلَ من كشف هجمات البتر — إذا أسقط مهاجم الأجزاء الأخيرة، يفشل فك التشفير على جانب العميل. AES-GCM في Web Crypto لا يمتلك هذه الخاصية؛ ستحتاج إلى بناء كشف البتر بنفسك (عدد الأجزاء في AAD، أو تجزئة شاملة للملف تُتحقق بعد فك التشفير).
Argon2 في المتصفح
لاشتقاق المفاتيح المبني على كلمة مرور في المتصفح، Argon2id عبر WASM هو أفضل ممارسة عام 2026. الخيارات:
- argon2-browser: مكتبة WASM مخصصة لـ Argon2، ~200 كيلوبايت
- libsodium.js: Argon2id عبر
crypto_pwhash، إذا كنت تستخدم libsodium أصلاً - @noble/hashes: Argon2id بـ JS خالصة، ~15 كيلوبايت، أبطأ بـ 3-5 مرات من WASM
مثال مع argon2-browser:
import argon2 from 'argon2-browser';
const result = await argon2.hash({
pass: password,
salt: salt, // Uint8Array، 16+ بايت
type: argon2.ArgonType.Argon2id,
time: 3,
mem: 65536, // كيلوبايت، أي 64 ميجابايت
parallelism: 4,
hashLen: 32,
});
// result.hash هو Uint8Array يمكن استخدامه كمفتاح AES-256
اضبط المعاملات بما يناسب انتظار المستخدم المستهدف. الخط الأساسي لـ OWASP 2024 (m=19 MiB, t=2, p=1) يعمل في ~300-500 مللي ثانية. الإعداد الأقوى (m=64 MiB, t=3, p=4) يعمل في ~1-2 ثانية على أجهزة حديثة.
تشفير ما بعد الكم عبر WASM
جرى توحيد Kyber (تغليف المفاتيح) وDilithium (التوقيعات) من قِبَل NIST في عام 2024 تحت مسمى ML-KEM وML-DSA. تنفيذات JavaScript موجودة (pq-crystals لديها مرجع) لكن إصدارات WASM كـ liboqs-js أسرع وأكثر قابلية للتدقيق.
لنقل الملفات، تُمكّنك KEMs ما بعد الكم من تغليف مفتاح ملف متماثل بمكوّن مفتاح عام مقاوم للكم. تحمي الخطط الهجينة (ML-KEM + X25519) من المهاجمين الكلاسيكيين والمستقبليين الكميين على حدٍّ سواء. شحن Chrome ML-KEM في مصافحات TLS في الإصدار 116 (2023)، لكن WASM على مستوى التطبيق يبقى المسار لمفاتيح محتوى الملفات.
اعتبارات حجم الحزمة
تُشحن ثنائيات WASM كجزء من حزمة JS أو تُجلب ببطء. الأحجام التقريبية (مضغوطة):
- libsodium.js الافتراضية: 200 كيلوبايت
- libsodium.js sumo: 600 كيلوبايت
- argon2-browser: 200 كيلوبايت
- liboqs-js (ما بعد الكم): 1 ميجابايت وأكثر
لصفحة هبوط تُشفّر داخل المتصفح، 200-300 كيلوبايت من WASM مقبولة إذا تحمّلت ببطء بعد تفاعل المستخدم. استخدم تلميحات rel="modulepreload" أو تخزين مؤقت بـ service worker لجعل التحميلات اللاحقة فورية.
تحقق من لوحة الشبكة في أدوات المطوّر للتأكد من تخزين ثنائي WASM في الذاكرة المؤقتة بعد التحميل الأول. رؤوس ذاكرة التخزين المؤقت غير المضبوطة قد تسبب إعادة التنزيل في كل زيارة.
تكلفة التصريف والإنشاء
WebAssembly.instantiate() يحلّل الثنائي ويصرّفه، وهو ما يستغرق 20-100 مللي ثانية لوحدة 200 كيلوبايت على سطح المكتب، و100-500 مللي ثانية على الأجهزة المحمولة. يحدث هذا مرة واحدة في الجلسة. خزّن الوحدة المصرَّفة في IndexedDB عبر تسلسل WebAssembly.Module للتحميل الأسرع لاحقاً.
WebAssembly.instantiateStreaming() يُتيح تنزيل الثنائي وتصريفه بالتوازي، موفراً 30-50% من وقت بدء التشغيل مقارنةً بـ instantiate() على استجابة محمّلة:
const response = fetch('/sodium.wasm');
const { instance } = await WebAssembly.instantiateStreaming(response, importObject);
مشكلات إدارة الذاكرة
تخصّص وحدات WASM ذاكرة في صفحات خطية (64 كيلوبايت لكل صفحة). يبدأ libsodium بذاكرة أولية صغيرة وينمو حسب الحاجة، لكن النموّ غير المحدود قد يصطدم بحدود المتصفح (عادةً 4 جيجابايت ذاكرة خطية في WASM ذي 32 بتاً). لتشفير الملفات متعددة الجيجابايت:
- بثّ الأجزاء عبر وحدة WASM، ولا تحمّل الملف كاملاً في ذاكرة WASM
- حرّر المخازن المؤقتة بعد كل جزء عبر
sodium.memzeroأو بإلغاء المراجع - راقب
WebAssembly.Memory.buffer.byteLengthفي الجلسات الطويلة
Memory64 (مُقترح، مُطبَّق جزئياً في Chrome) يزيل حدّ 4 جيجابايت. حالياً، المعالجة المجزّأة هي المسار الموثوق.
اعتبارات أمنية خاصة بـ WASM
يعمل WASM في الأصل ذاته للصفحة التي حمّلته، مرثاً قواعد CSP وCORS ذاتها. إذا حقن مهاجم كوداً في أصلك (XSS)، يمكنه استدعاء واجهات تصدير وحدة WASM. لا يوفّر WASM حدود أمان إضافية.
ضمانات الوقت الثابت: تحافظ معظم مكتبات التشفير المُصرَّفة إلى WASM على خصائص الوقت الثابت من مصدر C، لكن ترجمة WASM إلى JIT قد تُدخل كوداً متغيّر الوقت على بعض المنصات. لمعظم نماذج التهديد هذا أمر هامشي؛ للدفاع ضد مهاجمين محليين لديهم قياسات توقيت دقيقة، ضع هذه الفجوة في حسبانك.
الوصفة العملية
لتطبيق نقل ملفات في 2026:
- استخدم Web Crypto لـ AES-256-GCM وPBKDF2 وHMAC وSHA-256 وRSA-OAEP إذا احتجت RSA
- استخدم libsodium.js عبر WASM لتجزئة كلمات المرور بـ Argon2id
- استخدم libsodium.js لتشفير الملفات الكبيرة بشكل متدفق (
crypto_secretstream) - استخدم Ed25519/X25519 الأصلية حيثما دُعمت، وعُد إلى libsodium عدا ذلك
- حمّل WASM ببطء بعد تفاعل المستخدم لإبقاء الحزمة الأولية خفيفة
- قِس على الأجهزة المستهدفة؛ لا تفترض أن أرقام سطح المكتب تطابق الأجهزة المحمولة
يبقى HexaTransfer على Web Crypto AES-GCM لتشفير الملفات الجماعي لأن المسار المُسرَّع عتادياً هو الأسرع. WASM محجوز للخوارزميات التي لا تستطيع توفيرها واجهات API الأصلية.
جرّبها على hexatransfer.com — مجاني، بدون حساب، حتى 10 جيجابايت.
أرسل ملفات كبيرة بأمان مع تشفير من طرف إلى طرف
انقل ملفات حتى 10 جيجابايت مجاناً مع تشفير من طرف إلى طرف. لا حاجة لحساب. يتم تشفير ملفاتك في متصفحك قبل الرفع — لا أحد آخر يستطيع قراءتها.
إرسال ملف