طرح امضای APK v3، طرح امضای APK v3

اندروید 9 از چرخش کلید APK پشتیبانی می‌کند که به برنامه‌ها این امکان را می‌دهد تا کلید امضای خود را به عنوان بخشی از به‌روزرسانی APK تغییر دهند. برای عملی کردن چرخش، APKها باید سطوح اعتماد بین کلید امضای جدید و قدیمی را نشان دهند. برای پشتیبانی از چرخش کلید، طرح امضای APK را از نسخه ۲ به نسخه ۳ به‌روزرسانی کردیم تا بتوانیم از کلیدهای جدید و قدیمی استفاده کنیم. V3 اطلاعاتی در مورد نسخه های SDK پشتیبانی شده و یک ساختار اثبات چرخش به بلوک امضای APK اضافه می کند.

بلوک امضای APK

برای حفظ سازگاری با فرمت APK v1، امضاهای APK v2 و v3 در یک بلوک امضای APK که بلافاصله قبل از فهرست مرکزی ZIP قرار دارد، ذخیره می‌شوند.

فرمت بلوک امضای APK v3 مانند v2 است. امضای v3 APK به عنوان یک جفت ID-مقدار با شناسه 0xf05368c0 ذخیره می‌شود.

بلوک طرح امضای APK v3

طرح v3 بسیار شبیه به طرح v2 طراحی شده است. فرمت کلی یکسانی دارد و از همان شناسه‌های الگوریتم امضا ، اندازه‌های کلید و منحنی‌های EC پشتیبانی می‌کند.

با این حال، طرح v3 اطلاعاتی در مورد نسخه های SDK پشتیبانی شده و ساختار اثبات چرخش اضافه می کند.

قالب

بلوک طرح امضای APK v3 در داخل بلوک امضای APK تحت شناسه 0xf05368c0 ذخیره می‌شود.

قالب طرح امضای APK بلوک v3 از فرمت v2 پیروی می کند:

  • دنباله طول پیشوند signer با پیشوند طول:
    • signed data با پیشوند طول:
      • دنباله پیشوند طولی از digests پیشوند طول:
        • signature algorithm ID (4 بایت)
        • digest (پیشوند طول)
      • دنباله پیشوند طول certificates های X.509 :
        • certificate X.509 با پیشوند طول (فرم ASN.1 DER)
      • minSDK (uint32) - اگر نسخه پلتفرم زیر این عدد باشد، این امضاکننده باید نادیده گرفته شود.
      • maxSDK (uint32) - اگر نسخه پلتفرم بالاتر از این عدد باشد، این امضاکننده باید نادیده گرفته شود.
      • دنباله طول-پیشوند از additional attributes طول-پیشوند:
        • ID (uint32)
        • value (طول متغیر: طول ویژگی اضافی - 4 بایت)
        • ID - 0x3ba06f8c
        • value - ساختار اثبات چرخش
    • minSDK (uint32) - تکراری از مقدار minSDK در بخش داده امضا شده - برای رد شدن از تأیید این امضا در صورتی که پلت فرم فعلی در محدوده نباشد استفاده می شود. باید با مقدار داده امضا شده مطابقت داشته باشد.
    • maxSDK (uint32) - تکراری از مقدار maxSDK در بخش داده های امضا شده - برای رد شدن از تأیید این امضا در صورتی که پلت فرم فعلی در محدوده نباشد استفاده می شود. باید با مقدار داده امضا شده مطابقت داشته باشد.
    • دنباله طول-پیشوند signatures طول-پیشوند:
      • signature algorithm ID (uint32)
      • signature با پیشوند طول روی signed data
    • public key با پیشوند طول (SubjectPublicKeyInfo، فرم ASN.1 DER)

سازه‌های گواهی چرخش اثبات‌شده و مورد اعتماد قدیمی

ساختار اثبات چرخش به برنامه ها اجازه می دهد تا گواهی امضای خود را بدون مسدود شدن در سایر برنامه هایی که با آنها ارتباط برقرار می کنند بچرخانند. برای انجام این کار، امضای برنامه حاوی دو داده جدید است:

  • ادعا برای اشخاص ثالث که گواهی امضای برنامه را می توان در هر کجا که به پیشینیان آن اعتماد کرد، اعتماد کرد.
  • گواهی های امضای قدیمی برنامه که خود برنامه همچنان به آنها اعتماد دارد

ویژگی اثبات چرخش در بخش داده‌های امضا شده از یک فهرست به‌تنهایی تشکیل شده است که هر گره حاوی یک گواهی امضا است که برای امضای نسخه‌های قبلی برنامه استفاده می‌شود. این ویژگی شامل ساختارهای داده اثبات چرخش مفهومی و گواهی‌های قدیمی مورد اعتماد است. لیست بر اساس نسخه با قدیمی ترین گواهی امضای مربوط به گره ریشه مرتب شده است. ساختار داده اثبات چرخش با امضای گواهی در هر گره با علامت بعدی در لیست ساخته می‌شود، و بنابراین هر کلید جدید را با شواهدی مبنی بر اینکه باید به اندازه کلید(های کلیدی) قدیمی‌تر قابل اعتماد باشد، آغشته می‌کند.

ساختار داده گواهی‌های قدیمی با اضافه کردن پرچم‌هایی که عضویت و ویژگی‌های آن در مجموعه را نشان می‌دهد، ساخته می‌شود. به عنوان مثال، ممکن است پرچمی وجود داشته باشد که نشان می دهد گواهی امضا در یک گره معین برای دریافت مجوزهای امضای Android قابل اعتماد است. این پرچم به سایر برنامه‌های امضا شده توسط گواهی قدیمی‌تر اجازه می‌دهد تا همچنان مجوز امضای تعریف شده توسط برنامه امضا شده با گواهی امضای جدید را داشته باشند. از آنجایی که کل ویژگی اثبات چرخش در بخش داده های امضا شده فیلد signer v3 قرار دارد، توسط کلید مورد استفاده برای امضای apk حاوی محافظت می شود.

این قالب از کلیدهای امضای متعدد و همگرایی گواهی های امضای اجداد مختلف به یک (چند گره شروع به یک سینک مشترک) جلوگیری می کند.

قالب

اثبات چرخش در بلوک طرح امضای APK v3 تحت شناسه 0x3ba06f8c ذخیره می‌شود. فرمت آن این است:

  • دنباله طول-پیشوند از levels با پیشوند طول:
    • signed data با پیشوند طول (با گواهی قبلی - در صورت وجود)
      • certificate X.509 با پیشوند طول (فرم ASN.1 DER)
      • signature algorithm ID (uint32) - الگوریتم مورد استفاده توسط cert در سطح قبلی
    • flags (uint32) - پرچم‌هایی که نشان می‌دهند که آیا این گواهی باید در ساختار گواهی‌های قدیمی اعتماد باشد یا نه، و برای کدام عملیات.
    • signature algorithm ID (uint32) - باید با یکی از بخش داده های امضا شده در سطح بعدی مطابقت داشته باشد.
    • signature با پیشوند طول روی signed data بالا

گواهی های متعدد

امضاکنندگان چندگانه پشتیبانی نمی‌شوند و Google Play برنامه‌های امضا شده با چندین گواهی را منتشر نمی‌کند.

تأیید

در اندروید 9 و بالاتر، فایل‌های APK را می‌توان بر اساس طرح امضای APK نسخه 3، نسخه 2، یا طرح v1 تأیید کرد. پلتفرم‌های قدیمی‌تر امضاهای v3 را نادیده می‌گیرند و سعی می‌کنند امضاهای v2 و سپس v1 را تأیید کنند.

فرآیند تأیید امضای APK

شکل 1. فرآیند تأیید امضای APK

تأیید طرح امضای APK v3

  1. بلوک امضای APK را پیدا کنید و تأیید کنید که:
    1. دو فیلد اندازه بلوک امضای APK حاوی یک مقدار است.
    2. ZIP Central Directory بلافاصله پس از ZIP End of Central Directory ثبت می شود.
    3. پایان ZIP از دایرکتوری مرکزی با داده های بیشتری دنبال نمی شود.
  2. اولین بلوک طرح امضای APK v3 را در داخل بلوک امضای APK قرار دهید. اگر بلوک v3 وجود دارد، به مرحله 3 بروید. در غیر این صورت، به تأیید APK با استفاده از طرح v2 برگردید.
  3. برای هر signer در بلوک طرح امضای APK v3 با حداقل و حداکثر نسخه SDK که در محدوده پلتفرم فعلی قرار دارد:
    1. قوی ترین signature algorithm ID پشتیبانی شده را از signatures انتخاب کنید. ترتیب قدرت به هر نسخه پیاده سازی/پلتفرم بستگی دارد.
    2. signature مربوطه را از signatures در برابر signed data با استفاده از public key تأیید کنید. (اکنون تجزیه signed data امن است.)
    3. بررسی کنید که نسخه‌های حداقل و حداکثر SDK در داده‌های امضا شده با آنچه برای signer مشخص شده است مطابقت داشته باشند.
    4. بررسی کنید که لیست مرتب شده شناسه های الگوریتم امضا در digests و signatures یکسان است. (این کار برای جلوگیری از حذف/افزودن امضا است.)
    5. خلاصه محتویات APK را با استفاده از الگوریتم خلاصه مشابه الگوریتم خلاصه مورد استفاده توسط الگوریتم امضا محاسبه کنید .
    6. بررسی کنید که خلاصه محاسبه شده با digest مربوطه از digests یکسان است.
    7. بررسی کنید که SubjectPublicKeyInfo اولین certificate با public key یکسان است certificates
    8. اگر ویژگی اثبات چرخش برای signer وجود دارد، بررسی کنید که ساختار معتبر است و این signer آخرین گواهی در لیست است.
  4. اگر دقیقاً یک signer در محدوده پلتفرم فعلی پیدا شود و مرحله 3 برای آن signer موفقیت آمیز باشد، تأیید موفقیت آمیز است.

اعتبار سنجی

برای آزمایش اینکه آیا دستگاه شما نسخه 3 را به درستی پشتیبانی می‌کند، آزمایش‌های PkgInstallSignatureVerificationTest.java CTS را در cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ اجرا کنید.