۲۴ کلمه: هویت رمزنگاری شده چیست
یک هویت رمزنگاری شده رمز عبور نیست: هیچ سروری آن را ذخیره نمیکند و قابل بازیابی نیست. توضیحی آموزشی از مکانیسم BIP39، اینکه چرا دقیقاً بیست و چهار کلمه، و چه بار واقعی بر دوش کسی است که آنها را در اختیار دارد.
تفاوت بین رمز عبور و هویت
در مدل کلاسیک اینترنت، یک رمز عبور، اثبات هویت است. کاربر هویتی دارد — یک نام، یک ایمیل، یک شماره مشتری — و برای اثبات اینکه او همان کسی است که ادعا میکند، رمز عبوری ارائه میدهد که سرور آن را با اثری که ذخیره کرده مقایسه میکند. اگر اثرها مطابقت داشته باشند، سرور جلسه را مجاز میکند. اگر رمز عبور گم شود، کاربر همچنان همان کاربر است؛ آنچه از دست میدهد اثبات است، و رویهای برای بازیابی آن وجود دارد — ایمیلی به آدرس ثبت شده، یک سوال امنیتی — تا آن را بازگرداند.
هویت رمزنگاری به گونهای دیگر عمل میکند. این در وهله اول، یک راز ریاضی کامل و مستقل است، نه اعتباری که کسی آن را با اثری ذخیره شده مقایسه کند. مهم نیست کجا قرار دارد — روی کاغذ، در یک دستگاه، یا حتی در سرور شخص دیگری —: هویت به واسطه ریاضیات خود وجود دارد، نه به واسطه کسی که آن را تایید میکند. در اینجا ویژگی مشابه آنچه در «SHA-256 واقعاً چیست» دیدیم ظاهر میشود: مالکیت با نشان دادن راز ثابت نمیشود، بلکه با استفاده از آن برای امضا کردن ثابت میشود. امضای تولید شده به این روش میتواند توسط هر کسی با یک مقدار عمومی که از نظر ریاضی از خود راز مشتق شده است تأیید شود، بدون نیاز به دانستن خود راز، و بدون مداخله شخص ثالث در تأیید. کسی که راز را دارد، هویت است؛ کسی که آن را از دست میدهد، دیگر هویت نیست. حکم قطعی است: هیچکس وجود ندارد که بتوانید از او بخواهید هویتتان را به شما برگرداند. چنین کسی وجود ندارد، زیرا او از ابتدا آن را نداشته است.
آنچه بیست و چهار کلمه نشان میدهند
هویت رمزنگاری شده معمولاً با یک راز ریاضی سی و دو بایتی - دویست و پنجاه و شش بیت - نشان داده میشود. عددی که حفظ کردنش دشوار و بازنویسیاش بدون خطا دشوارتر است. صنعت رمزنگاری این مشکل را در سال ۲۰۱۳ با یک استاندارد کوچک و زیبا به نام BIP39 حل کرد: راهی برای نمایش آن دویست و پنجاه و شش بیت به عنوان دنبالهای از بیست و چهار کلمه گرفته شده از یک لیست رسمی دو هزار و چهل و هشت کلمهای. محاسبات پشت آن به زیبایی با هم جور در میآیند؛ هر کسی که بخواهد آن را با جزئیات ببیند، در حاشیه پیدا میکند.
شمارش تزئینی نیست. اگر کسی بیست و سه کلمه را به درستی بازنویسی کند و در کلمه بیست و چهارم اشتباه کند، چکسام آن را تشخیص خواهد داد: نرمافزار به او خواهد گفت «این دنباله معتبر نیست». اگر کسی تمام بیست و چهار کلمه را به درستی بازنویسی کند، نرمافزار بدون ابهام همان هویت را مشتق خواهد کرد. انتخاب لیست کلمات نیز عمدی است: کلمات واژگان BIP39 کوتاه، متفاوت از یکدیگر، بدون علائم تلفظی هستند که برای به حداقل رساندن اشتباهات آوایی و املایی انتخاب شدهاند. این واژگانی است که برای به خاطر سپردن، نوشتن و دیکته کردن توسط انسانها بدون خطا طراحی شده است.
از عبارت تا کلید
بیست و چهار کلمه، کلید رمزنگاری نیستند که پیامها را امضا میکنند. آنها یک نمایش قابل بازیابی از انتروپی اصلی هستند که از طریق فرآیندی معین به نام PBKDF2، به یک دانه (seed) شصت و چهار بایتی تبدیل میشوند. از آن دانه، باز هم به روشی معین، کلیدهای رمزنگاری خاصی که کاربر استفاده میکند مشتق میشوند: یک کلید خصوصی برای امضا و یک کلید عمومی متناظر که برای تأیید امضاها منتشر میشود. سازوکار یکسان در سیستمهای مختلف: ارزهای دیجیتال از منحنی secp256k1 استفاده میکنند؛ پروتکل Signal و بسیاری از سیستمهای مدرن از Ed25519 روی منحنی Curve25519 استفاده میکنند. برای یک منحنی خاص مانند Ed25519، استانداردهای BIP32 و SLIP-0010 آن دانه شصت و چهار بایتی را میگیرند و به طور معین، سی و دو بایتی را که کلید امضای مؤثر را تشکیل میدهند مشتق میکنند — همان سی و دو بایتی که مثال کد در بخش بعدی با آن شروع میشود.
این روش استانداردی است که کل صنعت، سازوکار را به کاربر ارائه میدهد —کیف پولهای ارز دیجیتال، مدیریت هویت غیرمتمرکز، Signal در بخش هویت پایدار خود، و Solo2 در میان آنها—: کاربر در عمل هرگز دانه یا کلیدهای مشتق شده را نمیبیند. او هنگام ایجاد هویت خود بیست و چهار کلمه را میبیند و در صورت تمایل، آنها را روی کاغذ یادداشت میکند. کلمات سپس بین دستگاههای او هنگامی که میخواهد هویت را منتقل کند جابجا میشوند: او آنها را در برنامه جدید وارد میکند، برنامه همان دانه، همان کلیدها و همان هویت را مشتق میکند. این یک سازوکار قابل حمل، از نظر رمزنگاری مستحکم و در حد معقول، قابل به خاطر سپردن است.
چگونه با کلید امضا کنیم (یک نگاه کوتاه در Zig)
در Zig، هنگامی که دانه سی و دو بایتی مشتق شده از بیست و چهار کلمه را داشته باشید، امضای یک پیام با Ed25519 در چند خط جا میگیرد:
const std = @import("std");
const Ed25519 = std.crypto.sign.Ed25519;
// 'semilla' son los 32 bytes derivados de las 24 palabras.
const par = Ed25519.KeyPair.create(semilla);
// Firmar un mensaje con la clave privada:
const mensaje = "Este mensaje lo escribí yo.";
const firma = try par.sign(mensaje, null);
// Cualquiera con la clave pública del par puede verificar:
try Ed25519.Signature.verify(firma, mensaje, par.public_key);
عملیات امضا شصت و چهار بایت تولید میکند —که امضا نامیده میشود— که فقط میتوانسته از کلید خصوصی متناظر تولید شده باشد. تأیید عمومی است: هر کسی با کلید عمومی میتواند بررسی کند که امضا با پیام مطابقت دارد. بدون کلید خصوصی، هیچکس نمیتواند امضای معتبری برای آن پیام تولید کند؛ با کلید عمومی، همه میتوانند تشخیص دهند که آیا یک امضا معتبر است یا خیر. این عدم تقارن همان چیزی است که به امضاکننده اجازه میدهد بدون به اشتراک گذاشتن راز، اصالت خود را ثابت کند.
مثال قبلی نسخه حداقلی دفترچه راهنما است. در کد واقعی Solo2، زنجیره از دو فایل عبور میکند: یکی در JavaScript که در مرورگر کاربر قرار دارد و آنتروپی را از بیست و چهار کلمه بازسازی میکند، و دیگری در Zig در کتابخانه zcatcrypto که آن آنتروپی را میگیرد و کلیدهای رمزنگاری خاص را مشتق میکند. با شروع از سمت مرورگر:
// solo2/web-app/js/lib/bip39.js
async function mnemonicToEntropy(mnemonic, lang) {
const validation = await validateMnemonic(mnemonic, lang);
if (!validation.valid) {
return { entropy: null, valid: false, error: validation.error };
}
const wordlist = WORDLISTS[lang || 'en'];
const words = mnemonic.trim().split(/\s+/);
// Cada palabra aporta 11 bits (su índice en la lista de 2048).
let bits = '';
for (let i = 0; i < words.length; i++) {
bits += wordlist.indexOf(words[i]).toString(2).padStart(11, '0');
}
// 24 palabras = 264 bits. Los primeros 256 son la entropía.
const entropyBytes = new Uint8Array(32);
for (let j = 0; j < 32; j++) {
entropyBytes[j] = parseInt(bits.slice(j * 8, (j + 1) * 8), 2);
}
return { entropy: entropyBytes, valid: true };
}
آن سی و دو بایت آنتروپی، همراه با سی و دو بایت دیگر که در همان مرحله مشتق شدهاند، به ماژول WebAssembly در Zig میروند که کلیدهای Ed25519 واقعی را تولید میکند. تابع کامل، با پاکسازی نهایی حافظه، در یک صفحه جا میشود:
// zcatcrypto/wasm/bindings/identity.zig
const Ed25519 = std.crypto.sign.Ed25519;
const X25519 = std.crypto.dh.X25519;
export fn identity_generate() ?*IdentityHandle {
var seed: [64]u8 = undefined;
if (!common.getRandomBytes(&seed)) return null;
const handle = common.wasm_allocator.create(IdentityHandle) catch return null;
// Bytes 0..31: semilla determinista del par Ed25519 (firma).
const sign_kp = Ed25519.KeyPair.generateDeterministic(seed[0..32].*) catch {
common.wasm_allocator.destroy(handle);
return null;
};
handle.sign_secret = sign_kp.secret_key.toBytes();
handle.sign_public = sign_kp.public_key.toBytes();
// Bytes 32..63: secreto X25519 (para acordar claves de cifrado con el otro).
handle.exchange_secret = seed[32..64].*;
handle.exchange_public = X25519.recoverPublicKey(handle.exchange_secret) catch {
common.wasm_allocator.destroy(handle);
return null;
};
@memset(&seed, 0); // Borra la semilla de la memoria.
return handle;
}
دو جزئیات ارزش اشاره دارند. اول: یک دانه (seed) واحد همیشه همان جفت کلید را تولید میکند — دقیقاً همین است که امکان بازیابی هویت را با وارد کردن بیست و چهار کلمه در یک دستگاه جدید فراهم میکند. دوم: دانه به صراحت در آخرین خط از حافظه پاک میشود. پس از آن نقطه، حتی خود تابع هم نمیتواند کلیدها را بازسازی کند؛ کلمات کاربر تنها منبع خواهند بود.
در اینجا توقفی کوتاه لازم است، زیرا کل زنجیره ممکن است با یک نگاه سریع با یکی دیگر از اعضای این سه گانه اشتباه گرفته شود: هش. اینطور نیست. هش تابعی منحصر به فرد است که فشردهسازی میکند — بایتهای زیادی وارد میشوند، یک ردپای کوتاه خارج میشود و مسیر در همانجا به پایان میرسد. هویت رمزنگاری یک جفت ریاضی مکمل است: راز میماند و امضا میکند؛ همتای عمومی آن منتشر میشود و تأیید میکند. در جایی که هش اطلاعات را در یک جهت فرو میریزد، هویت عدم تقارنی را بین دو نیمه برقرار میکند. هش گواهی میدهد که چه چیزی گفته شده است؛ هویت گواهی میدهد که چه کسی آن را گفته است.
آنچه عبارت نیست
سه اشتباه رایج را باید برطرف کرد. عبارت به معنای واقعی کلمه یک رمز عبور نیست: با اثر انگشت ذخیره شده در سرور مقایسه نمیشود؛ بلکه برای بازسازی ریاضی هویت، در دستگاه کاربر وارد میشود. عبارت قابل بازیابی نیست: اگر گم شود، کسی نیست که آن را از او بخواهید؛ اگر کپی شود، هویت نیز کپی میشود. عبارت یک اعتبارنامه جدا شدنی از هویت نیست: عبارت خودِ هویت است. هر کسی آن را داشته باشد میتواند به عنوان آن هویت عمل کند، بدون اجازه اضافی، بدون فرآیند مجوز و بدون امکان بازیابی.
این ویژگی سوم است که وزن موضوع را تغییر میدهد. رمز عبور گمشده یک دردسر اداری است. یک هویت رمزنگاری گمشده، خود هویت است. یک تکه کاغذ حاوی عبارت که توسط اشخاص ثالث پیدا شود، خطر سرقت حساب نیست: بلکه واگذاری کل هویت است. وعده سیستم — اینکه هیچکس نمیتواند هویت شما را باطل کند یا شما را خودسرانه مسدود کند — به طور جداییناپذیری با مسئولیت تنها حافظ چیزی بودن همراه است که هیچکس نمیتواند آن را برای شما بازگرداند.
وعده و وزن
مدل هویت رمزنگاری معمولاً با صفت خود-حاکم —self-sovereign در ادبیات انگلیسی— توصیف میشود. انتخاب کلمه آگاهانه است و وضعیت را با دقت زیادی توصیف میکند. کاربر به معنای تقریباً قرون وسطایی بر هویت خود حاکم است: هیچ پادشاهی، هیچ صادرکنندهای، هیچ مرجع مرکزی آن را اعطا نمیکند؛ و هیچ یک از موارد فوق نیز نمیتوانند آن را پس بگیرند. اما کاربر نیز مانند پادشاه قرون وسطایی، تمام عواقب اشتباهات خود را بر عهده دارد: اگر مهر را گم کند، هیچ نایبالسلطنهای وجود ندارد که به جای او تصمیم بگیرد.
انتخاب بین هویت مدیریت شده توسط شخص ثالث و هویت خود-حاکم پاسخ صحیح جهانی واحدی ندارد. برای یک حساب کاربری در انجمنی بیاهمیت، هویت مدیریت شده احتمالاً با خطر متناسب است. اما برای یک هویت حرفهای که اسناد الزامآور قانونی را امضا میکند، برای یک هویت اقتصادی که از پساندازهای شخصی محافظت میکند، برای یک هویت ارتباط حرفهای با مشتریانی که اطلاعات حساسی را به امانت گذاشتهاند، موضوع تغییر میکند. در آنجا دیگر سوال این نیست که «آیا راحت است؟» بلکه این است که «چه کسی به جز من، قدرت عمل به عنوان من را دارد و تحت چه شرایطی؟».
این سازوکار در کجا در سیستمهای واقعی ظاهر میشود
BIP39 در سال ۲۰۱۳ در دنیای Bitcoin متولد شد و به سرعت در کل اکوسیستم ارزهای دیجیتال گسترش یافت: امروزه هر کیف پول جدی یک عبارت BIP39 دوازده یا بیست و چهار کلمهای را به عنوان پشتیبان هویت اقتصادی دارنده آن میپذیرد. خارج از ارزهای دیجیتال، همان مفهوم اساسی — جفت رمزنگاری که مالکیت را بدون واسطه اثبات میکند — در سیستمهای دیگر با دستور زبان متفاوت ظاهر میشود. کلیدهای SSH که یک مدیر سیستم برای دسترسی به سرورهای خود استفاده میکند، یک مورد کلاسیک است: یک کلید خصوصی که مدیر در دستگاه خود نگه میدارد و یک کلید عمومی که در هر سرور کپی میشود؛ هیچ نهاد قابل مقایسه با یک سرویس متمرکز مداخله نمیکند. پروتکل Signal از Ed25519 با متریال کلید پایدار در دستگاه استفاده میکند؛ eIDAS اروپایی، در بخش امضای واجد شرایط خود، بر همان اصل رمزنگاری استوار است، با این تفاوت که کلید به جای کاربر توسط یک ارائه دهنده خدمات اعتماد واجد شرایط نگهداری میشود.
Solo2، پلتفرم ناشر این نشریه، از یک عبارت BIP39 بیست و چهار کلمهای به عنوان هویت هر کاربر استفاده میکند. کاربر هنگام ایجاد حساب خود، کلمات را یک بار میبیند. آنها در هیچ سرور Solo2 یا هیچ کس دیگری ذخیره نمیشوند: اگر کاربر آنها را یادداشت کرده و نگه دارد، هویت خود را برای همیشه حفظ میکند. اگر آنها را گم کند، آنها را از دست داده است. این نتیجه منطقی معماری بدون اپراتور در میان است: اگر Solo2 میتوانست هویت را به کاربری که آن را گم کرده بازگرداند، میتوانست آن را به هر کسی که به Solo2 فشار میآورد تا آن را دریافت کند، بدهد.
مُهر بدون دیوان
یک پادشاه در قرون وسطی از طریق مُهر خود حکومت میکرد، اما او تنها با آن حکومت نمیکرد: در پسِ آن دیوانی قرار داشت، کاتبانی که سوابق را نگه میداشتند، درباری که قادر به تشخیص جعل بود و میتوانست با کمک شاهدان و حافظه نهادی، آنچه را که یک مُهر گمشده یا دزدیده شده در هالهای از ابهام باقی میگذاشت، بازسازی کند. کسی که امروز از بیست و چهار کلمه محافظت میکند، مُهر را دارد و هیچ چیز دیگر: نه دیوانی، نه کاتبی، نه حافظه نهادی که بتواند اختلافی را حل و فصل کند یا آنچه را که از دست رفته است بازگرداند. کاغذ تا شده در یک کشو، پلاک فلزی حکاکی شده، پاکت مهر و موم شده در امانت اسناد رسمی، چیزی جز تلاشی دستساز و لزوماً ناقص برای ساختن یک دیوان شخصی با ابزارهای یک فرد عادی نیست.
پادشاهی بدون دیوان دقیقاً مانند پادشاهی با دیوان حکومت میکند —تا روزی که مُهر را از دست بدهد، و در آن روز او از حکومت کردن باز میماند در حالی که هیچ کس برای دادخواهی باقی نمانده است.
این مقاله سهگانه مفهومی را که چرخه را آغاز کرد — hash، رمزگذاری، هویت — میبندد. این سه ایده بر روی یکدیگر ساخته شدهاند: hash اثر انگشت تغییرناپذیر را میدهد، رمزگذاری محرمانگی بدون شخص ثالث قابل اعتماد را میدهد، هویت مالکیت بدون شخص ثالث اعطاکننده را میدهد. هر سه دارای ویژگی هستند که ایدئولوژیک هم نیست: آنها تواناییهای فنی را که به طور سنتی در اختیار اپراتور بود، از مدیر سرویس به کاربر آن منتقل میکنند. آنها همچنین مسئولیتهایی را با خود منتقل میکنند. صحبت صادقانه در مورد هر یک از این سه مستلزم صحبت در مورد دو مورد دیگر نیز هست.
منابع و مطالعه بیشتر
- Palatinus, M.; Rusnak, P.; Voisine, A.; Bowe, S. — BIP-0039: Mnemonic code for generating deterministic keys، پیشنهاد بهبود Bitcoin در سال ۲۰۱۳. استاندارد دو فاکتو برای عبارتهای بازیابی در صنعت رمزنگاری.
- RFC 8032 — Edwards-Curve Digital Signature Algorithm (EdDSA)، شامل Ed25519. IETF، ژانویه ۲۰۱۷. مشخصات هنجاری طرح امضای مورد استفاده در بخش بزرگی از صنعت معاصر.
- RFC 2898 — PKCS #5: Password-Based Cryptography Specification، نسخه ۲.۰. IETF، سپتامبر ۲۰۰۰. الگوریتم PBKDF2 مورد استفاده در مشتق BIP39 از عبارت به دانه (seed) را تعریف میکند.
- مقررات (اتحادیه اروپا) ۹۱۰/۲۰۱۴ (eIDAS) و تکامل آن توسط مقررات (اتحادیه اروپا) ۲۰۲۴/۱۱۸۳ (eIDAS 2) — چارچوب اروپایی برای هویت الکترونیکی و امضای واجد شرایط. رژیمی متفاوت از خود-حاکم، اما از نظر مفهومی بر پایه همان اصول رمزنگاری.
- Allen, C. — The Path to Self-Sovereign Identity (2016). متنی کلاسیک درباره اصول و تعهدات مدل خود-حاکم، قدیمیتر اما مرتبط برای درک خانواده راهحلهای معاصر.