مقاله فنی

شناسایی XLSX دستکاری‌شده با dataIntegrity HMAC در HotXLS

HotXLS یک بلوک dataIntegrity منطبق را درون بسته‌های XLSX رمزنگاری‌شده Agile می‌نویسد و آن را هنگام باز کردن اعتبارسنجی می‌کند. HMAC-SHA-512 کل جریان EncryptedPackage، از جمله پیشوند هشت‌بایتی StreamSize آن، را می‌پوشاند و پیش از رمزگشایی هر بخش، روی متن رمزشده بررسی می‌شود، بنابراین یک رمز عبور اشتباه یا یک بسته دستکاری‌شده شناسایی می‌شود نه اینکه به آشغال رمزگشایی شود

رمزنگاری بدون یکپارچگی یک پاسخ نیمه است، و قالب‌های فایل Office این شکاف را آسان می‌کنند که نادیده گرفته شود، چون رمزنگاری از بیرون آنقدر کامل به نظر می‌رسد. فهمیدن اینکه هر لایه چه چیزی قول می‌دهد همان چیزی است که یک بازبینی امنیتی را کوتاه نگه می‌دارد

یک کتاب‌کار رمزنگاری‌شده واقعاً چه چیزی قول می‌دهد؟

رمزنگاری Agile، تعریف‌شده در [MS-OFFCRYPTO]، محرمانگی را از طریق AES در حالت CBC با کلیدی که از یک هش رمز عبور SHA-512 تکراری مشتق شده به شما می‌دهد. محرمانگی کل قول این ساختار است. CBC یک حالت احرازشده نیست: هیچ‌چیز درباره اینکه آیا متن رمزشده‌ای که رمزگشایی می‌کنید همان متن رمزشده‌ای است که نوشته شده نمی‌گوید

پیامد عملی مشخص است. بیت‌ها را در یک بسته رمزنگاری‌شده بچرخانید و CBC با خوشحالی آن‌ها را به یک متن ساده متفاوت رمزگشایی می‌کند. معمولاً یک خطای تجزیه ZIP جایی در پایین‌دست دریافت می‌کنید، چون یک جریان deflate خراب به‌ندرت زنده می‌ماند، اما «معمولاً» در آن جمله کار زیادی انجام می‌دهد، و یک خطای تجزیه‌گر در پایین‌دست جای وحشتناکی است برای فهمیدن اینکه یک فایل تغییر کرده. عنصر dataIntegrity برای پاسخ‌دادن مستقیم به این سؤال، پیش از رمزگشایی، با یک MAC روی بایت‌های دقیق وجود دارد

بررسی چطور اجرا می‌شود، و به چه ترتیبی

ترتیب همان بخش جالب‌توجه است. HotXLS کلید میانی را از رمز عبور مشتق می‌کند، کلید و مقدار HMAC رمزنگاری‌شده را از ویژگی‌های dataIntegrity با استفاده از IVهای مشتق‌شده از کلید بلوک رمزگشایی می‌کند، HMAC-SHA-512 را روی بسته رمزنگاری‌شده همان‌طور که ذخیره شده محاسبه می‌کند، و مقایسه می‌کند. فقط پس از آن است که رمزگشایی بخش‌ها آغاز می‌شود

بررسی MAC روی متن رمزشده به‌جای متن ساده همان انضباط استاندارد encrypt-then-MAC است، و همین چیزی است که بررسی را معنادار می‌کند: یک بسته دستکاری‌شده بدون اینکه هیچ بایت کنترل‌شده توسط مهاجم از مسیر رمزگشایی و inflate عبور کند رد می‌شود. هر دو مقایسه در مسیر باز کردن، هش تأییدکننده رمز عبور و مقدار HMAC، اختلاف‌ها را با XOR و OR در سراسر دایجست کامل انباشته می‌کنند به‌جای بازگشت زودهنگام روی اولین بایت نامتطابق، پس هیچ‌کدام یک موقعیت بایت را از طریق زمان‌بندی فاش نمی‌کند

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    // برای فایل‌های ساده، رمزنگاری‌شده Standard و رمزنگاری‌شده Agile کار می‌کند
    if Book.OpenEncrypted('incoming.xlsx', PasswordFromVault) = 1 then
      ProcessWorkbook(Book)
    else
      // رمز عبور اشتباه، یا بسته‌ای که HMAC مربوط به dataIntegrity آن مطابقت نداشت
      Quarantine('incoming.xlsx');
  except
    on E: Exception do
      Quarantine('incoming.xlsx: ' + E.Message);
  end;
  Book.Free;
end;

در سمت نوشتن هیچ‌چیز در کد شما تغییر نمی‌کند. SaveAsEncrypted آن بلوک را به‌طور خودکار صادر می‌کند، و salt‌ها، ورودی تأییدکننده و کلید HMAC از CryptGenRandom می‌آیند. اگر آن فراخوانی شکست بخورد، HotXLS به‌جای بازگشت به یک منبع ضعیف‌تر، خطا صادر می‌کند. یک CSPRNG شکست‌بسته پارانویا نیست؛ یک تنزل بی‌صدا به یک منبع تصادفی قابل‌پیش‌بینی، فایل‌هایی تولید می‌کند که رمزنگاری‌شده به نظر می‌رسند، هر آزمون عملکردی را پشت سر می‌گذارند، و بی‌ارزش هستند

چرا فایل‌های بدون این بلوک همچنان باز می‌شوند؟

چون تعداد زیادی از کتاب‌کارهای رمزنگاری‌شده Agile در گردش، توسط تولیدکننده‌هایی نوشته شده‌اند که dataIntegrity را کاملاً حذف می‌کنند، و رد کردن آن‌ها کار مشروع بسیار بیشتری را نسبت به آنچه محافظت می‌کند خراب می‌کند. HotXLS یکپارچگی را فقط زمانی موجود در نظر می‌گیرد که هر دو ویژگی، کلید HMAC رمزنگاری‌شده و مقدار HMAC رمزنگاری‌شده، آنجا و به‌درستی تشکیل شده باشند. در غیر این صورت اعتبارسنجی رد می‌شود و فایل مثل قبل باز می‌شود

این یک تصمیم سازگاری با یک پیامد امنیتی است که باید در مدل تهدید خودتان به‌طور صریح نام ببرید: نبود بلوک را نمی‌توان از حذف آن توسط یک مهاجم تشخیص داد، چون ویژگی‌ها بیرون از MACای هستند که خودشان حمل می‌کردند. اگر بر هر دو سر یک پایپ‌لاین کنترل دارید، یک بلوک گمشده را به‌عنوان یک شکست سیاست در سطح برنامه در نظر بگیرید. اگر فایل‌ها را از دنیای بیرون می‌پذیرید، با بررسی همان‌طور که هست رفتار کنید: یک سیگنال باارزش وقتی حاضر است و اصلاً سیگنالی نیست وقتی غایب است

رمز عبور برای ویرایش یک قرارداد است، نه یک مرز

کتاب‌کارهای کلاسیک XLS یک مکانیزم جداگانه را پشتیبانی می‌کنند که به‌طور معمول با رمزنگاری اشتباه گرفته می‌شود: رزرو ویرایش، همان درخواست «رمز عبور برای ویرایش» اکسل. HotXLS آن را از طریق SetModifyPassword در اختیار می‌گذارد، که رمز عبور، یک پرچم توصیه فقط‌خواندنی و نام کاربر رزروکننده را می‌گیرد، و وضعیت را از طریق IsWriteReserved گزارش می‌دهد. عبور یک رمز خالی رزرو را پاک می‌کند

آنچه نوشته می‌شود یک جفت رکورد WRITEPROT و FILESHARING است که پرچم توصیه فقط‌خواندنی، یک هش رمز عبور ۱۶ بیتی قدیمی و نام کاربر را به‌صورت یک رشته یونیکد BIFF8 حمل می‌کند. آن هش ۱۶ بیتی یک checksum است، نه یک دایجست رمزنگاری‌شده، و محتوای سند اصلاً رمزنگاری نمی‌شود. هرکسی که فایل را با هر ابزار دیگری باز کند همه‌چیز را می‌خواند. کار واقعی این ویژگی هماهنگی است: به نفر بعدی می‌گوید کسی این فایل را متعلق به خودش برای ویرایش می‌داند، در همان دسته‌ای که کنترل‌های سطح شیت پوشش‌داده‌شده در محافظت شیت XLSX و گزینه‌های مجاز قرار دارد

var
  Book: IXLSWorkbook;   // شمارش‌شده با interface: Free نکنید
begin
  Book := TXLSWorkbook.Create;
  if Book.Open('shared-model.xls') = 1 then
  begin
    // توصیه فقط‌خواندنی، رزروشده توسط سرویس گزارش‌گیری
    Book.SetModifyPassword('edit-me', True, 'Reporting Service');

    if Book.IsWriteReserved then
      Book.SaveAs('shared-model.xls', xlExcel97);
  end;
end;

از هر دو لایه برای همان کاری استفاده کنید که در آن خوب است. محرمانگی واقعی از SaveAsEncrypted با یک رمز عبور که هیچ‌کس خارج از مخاطب آن را ندارد می‌آید، که خروجی AES-256 توضیح داده‌شده در خروجی XLSX محافظت‌شده با AES را تولید می‌کند. رزرو ویرایش زمانی روی آن اضافه می‌شود که کتاب‌کار یک مصنوع ویرایش مشترک است و می‌خواهید اکسل پیش از اینکه کسی روی آن ذخیره کند بپرسد

چه چیزی را در یک مسیر دریافت نامعتبر بررسی کنیم

اعتبارسنجی یکپارچگی از بار رمزنگاری‌شده محافظت می‌کند، نه از ظرف اطراف آن. یک فایل XLSX یک آرشیو ZIP است، و ساختار آرشیو پیش از اجرای هرگونه منطق رمزنگاری تجزیه می‌شود، پس اعتبارسنجی در سطح ظرف اول در زنجیره جای دارد؛ حالت‌های شکست خاص در اعتبارسنجی end-of-central-directory زیپ برای XLSX نامعتبر پوشش داده شده است. پس از آن، با یک شکست یکپارچگی و یک رمز عبور اشتباه به‌عنوان یک رویداد عملیاتی یکسان رفتار کنید، چون از سمت شما آن‌ها ذاتاً غیرقابل‌تشخیص هستند، و هر دو یعنی نمی‌توان به فایل اعتماد کرد که همان چیزی است که فرستنده فکر می‌کند

ثبت کنید کدام فایل‌ها اصلاً یک بلوک dataIntegrity حمل می‌کردند. روی چند هزار سند، آن آمار چیز مفیدی درباره ابزار فرستندگان شما به شما می‌گوید، و یک بررسی به‌ازای هر فایل را به یک مشاهده سطح‌ناوگان قابل‌اقدام تبدیل می‌کند

HotXLS فایل‌های XLS، XLSX و ODS را از Delphi و C++Builder بدون نصب Excel می‌خواند و می‌نویسد، و مسیرهای رمزنگاری Standard و Agile طبق [MS-OFFCRYPTO] را در Pascal پیاده‌سازی می‌کند. APIهای رمزنگاری، محافظت و کتاب‌کار در صفحه کامپوننت صفحه‌گسترده Delphi HotXLS مستند شده‌اند