طول مفتاح SM4
16 بايت 128 بت بالضبط: 16 بايت، تُكتب على شكل 32 خانة Hex أو 16 حرف ASCII. لا توجد مفاتيح SM4 بطول 192 أو 256 بت.
شفّر وفك شفرة SM4 أونلاين. إذا فشل فك الشفرة تحدّد الأداة الخاطئ: الوضع أم الحشو أم IV أم الترميز، وتقترح الإصلاح. تعمل في متصفحك ولا يُرفع شيء. ECB وCBC وCTR وCFB وOFB؛ حشو PKCS#7 أو صفري أو بدون حشو.
يحوّل ECB الكتل المتساوية إلى نص مشفّر متساوٍ ويسرّب الأنماط — لا تستخدمه إلا للتخاطب مع نظام يشترطه.
CTR وCFB وOFB أوضاع تدفّقية: بلا حشو، والنص المشفّر بطول النص الصريح نفسه.
تشخيص تلقائي
—
يتطلّب OpenSSL 3. يتضمّن الأمر المفتاح الذي أدخلته.
| المفتاح | 0123456789abcdeffedcba9876543210 |
|---|---|
| النص الصريح | 0123456789abcdeffedcba9876543210 |
| النص المشفّر بعد تعمية واحدة | 681edf34d206965e86b3e94f536e4246 |
| النص المشفّر بعد 1,000,000 تعمية | 595298c7c6fd271f0402f804c33d3f66 |
كتبه وراجعه مطوّرون يبنون أدوات تعمية. كل نص مشفّر وكل عدد بايتات مذكور في هذه الصفحة يحسبه محرّك الأداة وتتحقّق منه الاختبارات.
16 بايت 128 بت بالضبط: 16 بايت، تُكتب على شكل 32 خانة Hex أو 16 حرف ASCII. لا توجد مفاتيح SM4 بطول 192 أو 256 بت.
681edf34d206965e86b3e94f536e4246 عندما يكون المفتاح والنص الصريح 0123456789abcdeffedcba9876543210، يكون الناتج بعد تعمية واحدة 681edf34d206965e86b3e94f536e4246.
32 جولة كتل بطول 16 بايت (128 بت)، تُشفَّر في 32 جولة.
أول 16 بايت لا. أول 16 بايت فقط تُفكّ بشكل خاطئ، ويظل الحشو في الكتلة الأخيرة يجتاز الفحص.
خوارزمية SM4 هي الشفرة الكتلية في معايير التعمية التجارية الصينية. صدرت أولًا باسم GM/T 0002-2012، ثم أصبحت المعيار الوطني GB/T 32907-2016 (النافذ منذ 1 مارس 2017)، وأُضيفت إلى المعيار الدولي ISO/IEC 18033-3 بتعديل صدر عام 2021. وهي شفرة متماثلة: المفتاح نفسه بطول 128 بت يشفّر ويفكّ الشفرة، وتعمل على كتل بطول 128 بت، أي 16 بايت في كل مرة — وهو حجم الكتلة نفسه في AES.
داخليًا، تُقسَم كل كتلة إلى أربع كلمات بطول 32 بت وتمرّ عبر 32 جولة. في كل جولة تُمزج ثلاث من الكلمات مع مفتاح الجولة، ويمرّ الناتج عبر صندوق استبدال (S-box) بطول 8 بتات ثم تحويل خطي، ثم يُدمج في الكلمة الرابعة. تُشتق مفاتيح الجولات الـ32 من المفتاح باستخدام مجموعتين ثابتتين من الثوابت، وفكّ الشفرة هو الحساب نفسه مع مفاتيح الجولات بترتيب معكوس.
لا تعالج الشفرة الكتلية وحدها إلا 16 بايت بالضبط، لذا تمرّ البيانات الحقيقية دائمًا عبر وضع تشغيل. تقدّم هذه الأداة الأوضاع الخمسة الكلاسيكية: ECB وCBC اللذين يعملان على كتل كاملة ويحتاجان إلى حشو، وCTR وCFB وOFB التي تحوّل SM4 إلى شفرة تدفّقية بلا أي حشو. ومعظم حالات فشل فكّ الشفرة لا علاقة لها بـSM4 نفسه — بل تنتج عن اختلاف الطرفين في الوضع أو الحشو أو IV أو ترميز النص أو طريقة تحويل سلسلة المفتاح إلى بايتات، بل إن المكتبات لا تتفق حتى على معنى «SM4» المجرّد.
واجهة Web Crypto API المدمجة في المتصفحات لا تتضمّن SM4، لذا تحمل هذه الصفحة تنفيذها الخاص وتشغّله محليًا. وهو مُختبَر مقابل متجهَي اختبار GB/T 32907، ومُتحقَّق منه بالمقارنة مع OpenSSL 3 في كل الأوضاع.
// SM4-CBC with PKCS#7 padding using Node.js and its bundled OpenSSL 3.
// Key and IV are both exactly 16 bytes (32 hex digits).
const crypto = require('node:crypto');
const key = Buffer.from('0123456789abcdeffedcba9876543210', 'hex');
const iv = Buffer.from('fedcba98765432100123456789abcdef', 'hex');
const cipher = crypto.createCipheriv('sm4-cbc', key, iv);
const ciphertext = Buffer.concat([cipher.update('hello', 'utf8'), cipher.final()]);
console.log(ciphertext.toString('base64')); // fUQPRg2HAXHGz5ZslzCpSQ==
const decipher = crypto.createDecipheriv('sm4-cbc', key, iv);
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
console.log(plaintext.toString('utf8')); // hello عندما يفشل فكّ الشفرة، تعيد الصفحة المحاولة بترميز النص المشفّر وصيغة المفتاح والوضع وIV والحشو وترميز النص، وتعرض الإعدادات التي تُنتج نصًا مقروءًا.
بنقرة واحدة تُضبط افتراضيات OpenSSL أو Hutool أو sm-crypto أو gm-crypt أو tjfoc/gmsm — وهي مكتبات لا تتفق حتى على أن «SM4» المجرّد يعني ECB أم CBC.
ECB وCBC وCTR وCFB وOFB مع PKCS#7 أو الحشو الصفري أو بدون حشو. ويمكن أن يكون النص الصريح UTF-8 أو GBK، وهو الترميز الذي يُنتجه كود Java القديم على Windows الصيني. وضع GCM غير مدعوم.
ولّد مفتاحًا أو IV عشوائيًا بطول 16 بايت بنقرة واحدة، أو أدخله بالشكل الذي يكتبه به كودك. ويؤكّد عدّاد البايتات المباشر أن لديك 16 بايت بالضبط قبل أن تبدأ البحث عن أسباب أخرى.
نتيجتا الملحق A مطبوعتان في جدول ويمكن تحميل الأولى بنقرة واحدة، فتستطيع التحقق من أي تنفيذ لـSM4 مقابل المعيار.
تأتي كل نتيجة مع أمر openssl enc الذي يعيد إنتاجها، فتستطيع تأكيدها في الطرفية أو تسليمها لزميل.
يعمل محرّك SM4 محليًا. لا تغادر المفاتيح والبيانات الصفحة أبدًا، وتواصل الأداة العمل دون اتصال بالإنترنت.
openssl enc)-sm4 = CBC -sm4 اسم بديل لـ-sm4-cbc. يأخذ -K و-iv قيمًا بصيغة Hex، ويبقى PKCS#7 مفعّلًا ما لم تمرّر -nopad، والناتج بايتات خام ما لم تضف -base64 -A. وقيمة -K ذات الطول الخاطئ تُقصّ أو تُكمَل بالأصفار مع مجرد تحذير.
SmUtil.sm4(key)تمرّر Hutool الاسم المجرّد SM4، فتشغّله BouncyCastle بوضع ECB مع PKCS#7 (وتسمّيه JCE باسم PKCS5Padding). دوال السلاسل تستخدم UTF-8، وencryptHex تطبع Hex بأحرف صغيرة. ولوضع CBC استخدم new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv).
Cipher.getInstance("SM4")في وضع يحتاج إلى IV ولم يُمرَّر له، تولّد التعمية IV عشوائيًا بصمت، بينما يرمي فكّ الشفرة الخطأ no IV set when one expected — لذلك لا يمكن فكّ شفرة نص شُفِّر دون حفظ ذلك IV في أي مكان.
تعتمد sm4.encrypt(data, key) افتراضيًا ECB مع PKCS#7، وتتوقّع المفتاح سلسلة Hex من 32 خانة، وتعيد Hex بأحرف صغيرة. لا يغيّر الوضع إلا mode: 'cbc'؛ وأي قيمة أخرى تُبقي ECB بصمت. وتتصرّف sm-crypto-v2 بالطريقة نفسها، لكنها تستخدم IV كلّه أصفار عندما لا يُمرَّر iv إلى CBC.
تعتمد CBC افتراضيًا، وتأخذ المفتاح وIV سلسلتين بترميز UTF-8 من 16 حرفًا، وتعيد Base64. والمفتاح الذي لا تشكّل بايتاته UTF-8 صالحًا لا يمكن تمريره إليها أصلًا.
CryptSM4تختار الوضع باستدعاء crypt_ecb أو crypt_cbc. لا تقرأ set_key إلا أول 16 بايت، فيُقصّ المفتاح الأطول بصمت، والمفتاح الخاطئ يعيد عادةً بايتات فارغة بدل أي خطأ.
sm4تستخدم Sm4Cbc قيمة IV على مستوى الحزمة تبقى أصفارًا كلها حتى تُستدعى SetIV، وتحشو بـPKCS#7 حتى في CFB وOFB، وتتجاهل أخطاء إزالة الحشو — فالمفتاح الخاطئ يعيد nil دون أي خطأ.
المفتاح 0123456789abcdeffedcba9876543210، النص الصريح (Hex) 0123456789abcdeffedcba9876543210
681edf34d206965e86b3e94f536e4246
هذا هو المثال 1 من الملحق A في GB/T 32907-2016: للمفتاح والنص الصريح القيمة نفسها بطول 128 بت، وإذا شُفِّر النص مرة واحدة كان الناتج 681edf34d206965e86b3e94f536e4246. وإذا شُفِّر ذلك الناتج مرة بعد مرة حتى مليون مرة إجمالًا، كان الناتج 595298c7c6fd271f0402f804c33d3f66. القيمتان مطبوعتان في جدول متجهات الاختبار في هذه الصفحة، وقد حسبهما المحرّك نفسه الذي تستخدمه الآن. زر متجه اختبار GB/T 32907 يحمّل القيمة الأولى.
المفتاح 0123456789abcdeffedcba9876543210، IV fedcba98765432100123456789abcdef، النص الصريح: SM4 interop test: order 20260911-0042
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y
النص الصريح 37 بايت بترميز UTF-8. يحشوه PKCS#7 إلى 48 بايت، أي ثلاث كتل بطول 16 بايت، يكتبها Base64 في 64 حرفًا. زر تحميل مثال يملأ هذه القيم نفسها بالضبط، وتعرض لوحة OpenSSL أمرًا يعيد إنتاج سلسلة Base64 نفسها في الطرفية.
النص المشفّر أعلاه، بعد فكّ شفرته بـ IV 00000000000000000000000000000000
16 بايت مشوّهة، ثم ": order 20260911-0042"
يمزج CBC قيمة IV في الكتلة الأولى وحدها، بينما يقع حشو PKCS#7 في الكتلة الأخيرة، لذلك يمرّ فحص الحشو ولا يُصدر OpenSSL أي خطأ. تلاحظ هذه الصفحة أن الكتلة الأولى غير مقروءة، فتخبرك بأن المفتاح والوضع صحيحان وأن المشكلة في IV — أو أن أول 16 بايت من النص المشفّر هي نفسها IV.
إذا كنت تعرف المكتبة في الطرف الآخر، فاخترها من «مطابقة افتراضيات مكتبة». وإلا فاختر «شفّر» أو «فكّ الشفرة» وطابِق الوضع والحشو. الأوضاع التدفّقية (CTR وCFB وOFB) بلا حشو، لذلك يُعطَّل مُحدِّد الحشو معها.
طول كلٍّ منهما 16 بايت بالضبط. اختر الصيغة المكتوبة بها السلسلة — Hex أو نص أو Base64 — وراقب عدّاد البايتات حتى يصبح أخضر. أزرار «عشوائي» تولّد قيمًا جديدة.
في اتجاه «شفّر» اكتب نصًا (UTF-8 أو GBK) أو الصق بايتات Hex. وفي اتجاه «فكّ الشفرة» الصق النص المشفّر وحدّد هل هو Base64 أم Hex. تتحدّث النتيجة أثناء الكتابة.
انسخ الناتج، أو انقر «فكّ شفرة هذا النص» لنقله إلى تبويب فكّ الشفرة بالمفتاح وIV نفسيهما. وتعرض لوحة OpenSSL أمرًا يعيد إنتاج النتيجة.
يسرد التشخيص الإعدادات التي تُفكّ بها مدخلاتك إلى نص مقروء. طبّق أحدها بنقرة، أو اقرأ الملاحظة إذا فشلت أول 16 بايت فقط — فهذا يشير إلى IV.
سلسلة Hex من 32 حرفًا لا تساوي 16 بايت إلا إذا فُكّ ترميزها كـHex. أما إذا قُرئت كنص فهي 32 بايت يرفضها SM4 — أو، في كود يقصّ المفاتيح أو يكملها بصمت، مفتاح مختلف تمامًا.
المفتاح (نص): 0123456789abcdeffedcba9876543210 -> 32 بايت، مرفوض
المفتاح (Hex): 0123456789abcdeffedcba9876543210 -> 16 بايت
يجب أن يستخدم الطرفان الوضع نفسه. النص المشفّر بـCBC إذا فُكّت شفرته بـECB أعطى رموزًا مشوّهة في كل كتلة، وغالبًا ما يفشل في فحص الحشو في النهاية.
encrypt: SM4/CBC/PKCS5Padding decrypt: SM4/ECB/PKCS5Padding -> bad decrypt
encrypt: SM4/CBC/PKCS5Padding decrypt: SM4/CBC/PKCS5Padding, same IV
في CBC لا يُصدر IV الخاطئ أي خطأ: تخرج أول 16 بايت مشوّهة ويُفكّ الباقي بشكل طبيعي. إذا كانت بداية النص الصريح وحدها تالفة، فقارن قيمتي IV لدى الطرفين.
decrypt IV 00000000000000000000000000000000 -> 16 بايت مشوّهة + ": order 20260911-0042"
decrypt IV fedcba98765432100123456789abcdef -> "SM4 interop test: order 20260911-0042"
Base64 وHex طريقتان لكتابة البايتات نفسها. وقراءة إحداهما على أنها الأخرى تعطي الشفرة إدخالًا خاطئًا من البداية.
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y read as hex -> invalid
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y read as Base64 -> 48 bytes
لا يستطيع الحشو الصفري التمييز بين الحشو والبيانات، فالنص الصريح الذي ينتهي فعلًا ببايتات 0x00 يفقدها. استخدم PKCS#7 لكل ما ليس نصًا عاديًا.
zero padding: 61 62 00 -> decrypts to 61 62
PKCS#7: 61 62 00 -> decrypts to 61 62 00
يعامل OpenSSL الخيار sm4 على أنه CBC. أما BouncyCastle — ومن ثَمّ SmUtil.sm4(key) في Hutool — فيعامل SM4 على أنه ECB مع PKCS#7. فقد يختلف نظامان «يستخدمان SM4 فحسب» في الوضع.
Java: Cipher.getInstance("SM4") -> ECB + PKCS#7
OpenSSL: openssl enc -sm4 -> CBC Java: Cipher.getInstance("SM4/CBC/PKCS5Padding")
OpenSSL: openssl enc -sm4-cbc تستخدم getBytes() في Java دون تحديد مجموعة محارف الترميزَ الافتراضي للمنصة، وهو GBK على Windows الصيني مع JDK 17 أو أقدم. فيُشفَّر النص الصيني نفسه إلى نص مشفّر مختلف، ويفكّه الطرف الآخر إلى رموز مشوّهة.
"国密SM4 test".getBytes() // GBK on a Chinese Windows JDK <= 17 -> ECB ciphertext 3188d06cf28db70092f8753cbd5ee518
"国密SM4 test".getBytes(StandardCharsets.UTF_8) -> ECB ciphertext d830308b0ae4fa7b9a2b5d59f7f65ca5
pay=100.00 إلى pay=900.00، ويظل فكّ الشفرة ناجحًا. احسب رمز MAC على IV والنص المشفّر وتحقّق منه قبل فكّ الشفرة، مثلًا باستخدام مولّد HMAC.0123456789abcdeffedcba9876543210 إذا قُرئت كـHex فهي 16 بايت، أما إذا قُرئت كنص فهي 32 بايت وتُرفض. مُحدِّد الصيغة وعدّاد البايتات بجوار حقل المفتاح موجودان لالتقاط هذا الخطأ تحديدًا. PKCS5Padding في Java هو الحشو نفسه — إذ تمرّر BouncyCastle الاسمين عبر مسار الكود ذاته. أما الحشو الصفري فيضيف 0x00 حتى حدّ الكتلة التالية فقط. وعند فكّ الشفرة تزيل Hutool وBouncyCastle كل بايتات 0x00 في النهاية، بما فيها الأصفار التي كانت جزءًا حقيقيًا من البيانات، بينما تزيل مكتبة gmssl في Python بايتًا واحدًا فقط. ويتطلّب خيار «بدون حشو» أن يكون الإدخال عددًا صحيحًا من الكتل بطول 16 بايت. أما CTR وCFB وOFB فأوضاع تدفّقية لا تستخدم الحشو أبدًا. إذا انتهى النص بعد فكّ شفرته بمسافات شاردة أو مربّعات أو أسطر جديدة، فالحشو لم يُزَل: بيانات PKCS#7 المفكوكة دون حشو تحتفظ في آخرها بعدد n من البايتات قيمة كلٍّ منها n (وتظهر 0x09 و0x0A و0x0D كمسافات جدولة وأسطر جديدة)؛ حوّل الناتج إلى Hex وانظر إلى الكتلة الأخيرة. getBytes() على نظام Windows صيني — وكيف طُبعت النتيجة: Base64 أم Hex بأحرف صغيرة أم Hex بأحرف كبيرة. مع إعدادات متطابقة وIV ثابت، يُنتج أي تنفيذين صحيحين ناتجًا متطابقًا. وإن شككت في إحدى الأداتين، فتحقّق من كلتيهما أولًا مقابل متجه اختبار GB/T 32907. 0123456789abcdeffedcba9876543210، يجب أن يُشفَّر النص مرة واحدة إلى 681edf34d206965e86b3e94f536e4246، وأن يصبح بعد مليون مرة متسلسلة 595298c7c6fd271f0402f804c33d3f66. هذان المتجهان يختبران الشفرة الكتلية وحدها، لذا شفّر بعد ذلك نصًا ما بوضع CBC بمفتاح وIV ثابتين، وقارن الناتج بهذه الصفحة أو بأمر OpenSSL الذي تعرضه. المحرّك الذي تقوم عليه هذه الصفحة مُختبَر مقابل المتجهين كليهما، ومقابل OpenSSL 3 في الأوضاع الخمسة جميعها. openssl enc -sm4-cbc -K <32 hex digits> -iv <32 hex digits>: يأخذ -K المفتاح الخام بصيغة Hex، فلا دخل لأي كلمة مرور، ويُلغي -nopad حشو PKCS#7، ويقرأ -base64 -A أو يكتب Base64 في سطر واحد. انتبه لأمرين: -sm4 وحده يعني CBC، وقيمة -K ذات الطول الخاطئ تُقصّ أو تُكمَل بالأصفار مع مجرد تحذير. لوحة OpenSSL في هذه الصفحة تبني الأمر من إعداداتك الحالية؛ وبما أن openssl enc لا يدعم الحشو الصفري، تذكر اللوحة ذلك صراحةً بدل أن تطبع أمرًا لن يطابق النتيجة. SmUtil.sm4(key) في Hutool تمرّر الاسم SM4 فقط، فتكمله BouncyCastle إلى ECB مع PKCS#7 (أي PKCS5Padding في Java)؛ ولا يعني CBC إلا سلسلة كاملة مثل SM4/CBC/PKCS5Padding. وفي JavaScript تعتمد sm-crypto أيضًا ECB افتراضيًا، وتأخذ المفتاح سلسلة Hex من 32 خانة، وتطبع Hex بأحرف صغيرة، بينما تعتمد gm-crypt وضع CBC افتراضيًا، وتأخذ مفتاحًا نصيًا من 16 حرفًا، وتطبع Base64. ثم تحقّق من مجموعة محارف النص الصريح: دوال السلاسل في Hutool تستخدم UTF-8 دائمًا، لكن استدعاء getBytes() المجرّد على JDK 17 أو أقدم في Windows الصيني قد يعني GBK، وهذا يغيّر النص المشفّر. اختر المكتبة من مطابقة افتراضيات مكتبة لضبط كل ذلك بنقرة واحدة، أو أدخل القيم بنفسك؛ وإن لم تكن متأكدًا من إحداها، فالصق النص المشفّر على أي حال وسيجرّب التشخيص التلقائي تركيبات الوضع والحشو وIV والترميز. أدوات الأمن
فك تشفير AES أونلاين — GCM/CBC/CTR، عبارة مرور أو مفتاح خام، يكتشف تلقائيًا صيغة OpenSSL وCryptoJS "U2FsdGVkX1". يعمل 100% داخل المتصفح، والمفاتيح لا تغادر الصفحة أبدًا.
أدوات الأمن
أداة تشفير AES مجانية أونلاين — AES-128/192/256، GCM/CBC/CTR، عبارة مرور (PBKDF2) أو مفتاح خام. تعمل 100% داخل متصفحك؛ لا شيء يُرفع.
أدوات الأمن
ولّد تجزئات كلمات المرور بـ bcrypt وتحقق منها أونلاين — تكلفة قابلة للضبط، بادئات $2b$/$2a$/$2y$. 100% في متصفحك؛ كلمة مرورك لا تُرفع أبداً.
أدوات الأمن
الصق بيانات ست عشرية أو نصاً واحصل على 63 متغيّراً من CRC-8 وCRC-16 وCRC-32 دفعة واحدة. لديك قيمة تحقق لا تستطيع مطابقتها؟ اكتبها لتسمّي الأداة المتغيّر — MODBUS وCCITT-FALSE وXMODEM وKERMIT. يعمل كلياً داخل متصفحك.
أدوات الأمن
مولّد ومدقّق HMAC مجاني أونلاين. احسب HMAC-SHA256/SHA1/SHA384/SHA512 بمفاتيح Text أو Hex أو Base64 وإخراج Hex/Base64/Base64URL. كل شيء داخل متصفحك — المفاتيح لا تغادر الصفحة.
أدوات الأمن
فك ترميز رموز JWT أونلاين مع محلّل JWT المجاني. افحص الترويسة والحمولة والتوقيع وانتهاء الصلاحية والخوارزمية والمطالبات فوراً. 100% في المتصفح — رمزك لا يغادر جهازك. بلا تسجيل، بلا تتبّع.