در دسترس بودن یک محیط اجرای قابل اعتماد در یک سیستم بر روی یک تراشه (SoC) فرصتی را برای دستگاههای Android فراهم میکند تا خدمات امنیتی قوی و سختافزاری را برای سیستمعامل Android، سرویسهای پلتفرم و حتی برنامههای شخص ثالث ارائه کنند (در قالب برنامههای افزودنی مختص اندروید به معماری استاندارد Java Cryptography، به KeyGenParameterSpec
مراجعه کنید).
واژه نامه
در اینجا یک مرور سریع از اجزای Keystore و روابط آنها ارائه شده است.
-
AndroidKeyStore
- API و مؤلفه Android Framework که توسط برنامهها برای دسترسی به عملکرد Keystore استفاده میشود. این یک پیادهسازی از APIهای استاندارد معماری رمزنگاری جاوا است، اما افزونههای مخصوص اندروید را نیز اضافه میکند و از کد جاوا تشکیل شده است که در فضای فرآیند خود برنامه اجرا میشود.
AndroidKeyStore
درخواست های برنامه برای رفتار Keystore را با ارسال آنها به شبح keystore برآورده می کند. - دیمون فروشگاه کلید
- یک شبح سیستم Android که دسترسی به تمام عملکردهای Keystore را از طریق Binder API فراهم می کند. این دیمون مسئول ذخیرهسازی حبابهای کلیدی ایجاد شده توسط اجرای KeyMint (یا Keymaster) است که حاوی مواد کلید مخفی است، به طوری که Keystore بتواند آنها را ذخیره کند اما از آنها استفاده یا آشکار نکند.
- سرویس KeyMint HAL
- یک سرور AIDL که
IKeyMintDevice
HAL را پیاده سازی می کند و دسترسی به KeyMint TA اساسی را فراهم می کند. - برنامه مورد اعتماد KeyMint (TA)
- نرمافزاری که در یک زمینه امن اجرا میشود، اغلب در TrustZone روی یک SoC ARM، که تمام عملیات رمزنگاری امن را فراهم میکند. این برنامه به مواد کلید خام دسترسی دارد و تمام شرایط کنترل دسترسی کلیدها را قبل از اجازه استفاده از آنها تأیید می کند.
-
LockSettingsService
- جزء سیستم اندرویدی که مسئول احراز هویت کاربر، رمز عبور و اثر انگشت است. این بخشی از Keystore نیست، اما مرتبط است، زیرا Keystore از مفهوم کلیدهای محدودکننده احراز هویت پشتیبانی میکند: کلیدهایی که فقط در صورتی میتوانند استفاده شوند که کاربر احراز هویت را انجام داده باشد.
LockSettingsService
با Gatekeeper TA و Fingerprint TA تعامل می کند تا توکن های احراز هویت را به دست آورد که در اختیار دیمون keystore قرار می دهد و توسط KeyMint TA مصرف می شود. - دروازه بان TA
- مؤلفه ای که در محیط امن اجرا می شود و مسئول احراز هویت رمزهای عبور کاربر و تولید نشانه های احراز هویت است، برای اثبات به KeyMint TA استفاده می شود که احراز هویت برای یک کاربر خاص در یک زمان خاص انجام شده است.
- اثر انگشت TA
- مؤلفهای که در محیط امن اجرا میشود و مسئول احراز هویت اثر انگشت کاربر و تولید نشانههای احراز هویت است که برای اثبات به KeyMint TA استفاده میشود که احراز هویت برای یک کاربر خاص در یک زمان خاص انجام شده است.
معماری
Android Keystore API و KeyMint HAL زیربنایی مجموعه ای اساسی اما کافی از رمزنگاری های اولیه را فراهم می کند تا امکان اجرای پروتکل ها را با استفاده از کلیدهای کنترل شده با دسترسی سخت افزاری فراهم کند.
KeyMint HAL یک سرویس OEM ارائه شده توسط سرویس Keystore برای ارائه خدمات رمزنگاری سخت افزاری است. برای ایمن نگه داشتن مواد کلید خصوصی، اجرای HAL هیچ عملیات حساسی را در فضای کاربر یا حتی در فضای هسته انجام نمی دهد. در عوض، سرویس KeyMint HAL که در اندروید اجرا میشود، عملیات حساس را به یک TA که در نوعی محیط امن اجرا میشود، محول میکند.
معماری حاصل به این صورت است:

شکل 1. دسترسی به KeyMint.
KeyMint HAL API سطح پایینی است، توسط مؤلفههای داخلی پلتفرم استفاده میشود و در معرض توسعهدهندگان برنامه قرار نمیگیرد. جاوا API سطح بالاتری که برای برنامه ها در دسترس است در سایت برنامه نویس Android توضیح داده شده است.
کنترل دسترسی
Android Keystore یک مؤلفه مرکزی برای ذخیره و استفاده از کلیدهای رمزنگاری سخت افزاری، هم برای برنامه ها و هم برای سایر اجزای سیستم، ارائه می دهد. به این ترتیب، دسترسی به هر کلید منفرد معمولاً محدود به برنامه یا مؤلفه سیستمی است که کلید را ایجاد کرده است.
دامنه های فروشگاه کلید
برای پشتیبانی از این کنترل دسترسی، کلیدها به Keystore با یک توصیفگر کلید شناسایی می شوند. این توصیفگر کلید دامنه ای را نشان می دهد که توصیفگر به آن تعلق دارد، همراه با هویتی در آن دامنه.
برنامههای اندروید با استفاده از معماری رمزنگاری استاندارد جاوا، که کلیدها را با نام مستعار رشتهای شناسایی میکند، به Keystore دسترسی پیدا میکنند. این روش شناسایی نقشه های داخلی به دامنه APP
Keystore می شود. UID تماس گیرنده نیز برای رفع ابهام کلیدهای برنامه های مختلف گنجانده شده است و از دسترسی یک برنامه به کلیدهای دیگر جلوگیری می کند.
در داخل، کد فریمورک پس از بارگیری کلید، شناسه کلید عددی منحصربهفرد را نیز دریافت میکند. این شناسه عددی به عنوان شناسه برای توصیفگرهای کلید در دامنه KEY_ID
استفاده می شود. با این حال، کنترل دسترسی همچنان انجام می شود: حتی اگر یک برنامه یک شناسه کلید برای کلید برنامه دیگر پیدا کند، نمی تواند در شرایط عادی از آن استفاده کند.
با این حال، این امکان برای یک برنامه وجود دارد که استفاده از یک کلید را به یک برنامه دیگر (همانطور که توسط UID مشخص شده است) اعطا کند. این عملیات اعطایی یک شناسه گرنت منحصر به فرد را برمی گرداند، که به عنوان شناسه برای توصیفگرهای کلیدی در دامنه GRANT
استفاده می شود. باز هم، کنترل دسترسی همچنان انجام می شود: حتی اگر یک برنامه سوم شناسه کمک مالی را برای کلید دریافت کننده اعطا کند، نمی تواند از آن استفاده کند.
Keystore همچنین از دو دامنه دیگر برای توصیفگرهای کلید پشتیبانی می کند، که برای سایر اجزای سیستم استفاده می شود و برای کلیدهای ایجاد شده توسط برنامه در دسترس نیستند:
- دامنه
BLOB
نشان می دهد که هیچ شناسه ای برای کلید در توصیفگر کلید وجود ندارد. درعوض، توصیفگر کلید خود صفحه کلید را نگه میدارد و کلاینت ذخیرهسازی حباب کلید را مدیریت میکند. این توسط کلاینت هایی (به عنوان مثال،vold
) استفاده می شود که باید قبل از نصب پارتیشن داده به Keystore دسترسی داشته باشند. - دامنه
SELINUX
به اجزای سیستم اجازه می دهد تا کلیدها را به اشتراک بگذارند، با دسترسی توسط یک شناسه عددی که مربوط به یک برچسب SELinux است (به خط مشی SELinux برای keystore_key مراجعه کنید).
خط مشی SELinux برای keystore_key
مقادیر شناسه مورد استفاده برای توصیفگرهای کلید Domain::SELINUX
در فایل خط مشی keystore2_key_context
SELinux پیکربندی شده است. هر خط در این فایل ها یک عدد را به یک برچسب SELinux نشان می دهد، به عنوان مثال:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
مؤلفه ای که نیاز به دسترسی به کلید با شناسه 102 در دامنه SELINUX
دارد، باید خط مشی SELinux مربوطه را داشته باشد. به عنوان مثال، برای اجازه دادن به wpa_supplicant
برای دریافت و استفاده از این کلیدها، خط زیر را به hal_wifi_supplicant.te
اضافه کنید:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
شناسههای عددی کلیدهای Domain::SELINUX
به محدودههایی تقسیم میشوند تا از پارتیشنهای مختلف بدون برخورد پشتیبانی کنند:
پارتیشن | محدوده | فایل های پیکربندی |
---|---|---|
سیستم | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
سیستم توسعه یافته | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
محصول | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
فروشنده | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
مقادیر ویژه زیر برای پارتیشن سیستم تعریف شده است:
شناسه فضای نام | برچسب SEPolicy | UID | توضیحات |
---|---|---|---|
0 | su_key | N/A | کلید کاربر فوق العاده فقط برای آزمایش بر روی userdebug و ساخت های eng استفاده می شود. مربوط به ساخت های کاربر نیست. |
1 | shell_key | N/A | فضای نام موجود برای پوسته. بیشتر برای آزمایش استفاده می شود، اما می تواند در ساخت های کاربر نیز از خط فرمان استفاده شود. |
100 | vold_key | N/A | در نظر گرفته شده برای استفاده توسط ولد. |
101 | odsign_key | N/A | توسط دیمون امضای روی دستگاه استفاده می شود. |
102 | wifi_key | AID_WIFI(1010) | توسط زیرسیستم Wifi اندروید از جمله wpa_supplicant استفاده می شود. |
103 | locksettings_key | N/A | توسط LockSettingsService استفاده می شود |
120 | resume_on_reboot_key | AID_SYSTEM(1000) | توسط سرور سیستم اندروید برای پشتیبانی از رزومه در راه اندازی مجدد استفاده می شود. |
دسترسی به بردارها
Keystore اجازه می دهد تا علاوه بر کنترل دسترسی کلی به یک کلید، کنترل عملیاتی را که می توان روی یک کلید انجام داد. مجوزهای keystore2_key
در فایل KeyPermission.aidl
توضیح داده شده است.
مجوزهای سیستم
علاوه بر کنترلهای دسترسی به ازای هر کلید که در خطمشی SELinux برای keystore_key توضیح داده شده است، جدول زیر سایر مجوزهای SELinux را که برای انجام عملیاتهای مختلف سیستم و تعمیر و نگهداری لازم هستند، توضیح میدهد:
اجازه | معنی |
---|---|
add_auth | برای افزودن نشانه های اعتبار به Keystore لازم است. توسط ارائه دهندگان احراز هویت مانند Gatekeeper یا BiometricManager استفاده می شود. |
clear_ns | برای حذف همه کلیدها در یک فضای نام خاص مورد نیاز است. هنگامی که برنامه ها حذف می شوند به عنوان عملیات تعمیر و نگهداری استفاده می شود. |
list | مورد نیاز سیستم برای شمارش کلیدها بر اساس ویژگی های مختلف، مانند مالکیت یا اینکه آیا آنها محدود به احراز هویت هستند. این مجوز برای تماسگیرندگانی که فضاهای نام خود را میشمارند (که توسط مجوز get_info پوشش داده میشود) لازم نیست. |
lock | برای اطلاع دادن به فروشگاه کلید مبنی بر قفل بودن دستگاه مورد نیاز است، که به نوبه خود کلیدهای فوق العاده را خارج می کند تا اطمینان حاصل شود که کلیدهای محدود شده احراز هویت در دسترس نیستند. |
unlock | برای اطلاع دادن به فروشگاه کلید مبنی بر باز شدن قفل دستگاه، بازیابی دسترسی به سوپرکلیدهایی که از کلیدهای محدود احراز هویت محافظت می کنند، لازم است. |
reset | برای بازنشانی Keystore به پیشفرض کارخانه، حذف همه کلیدهایی که برای عملکرد سیستمعامل اندروید حیاتی نیستند، لازم است. |
تاریخچه
در اندروید 5 و پایینتر، اندروید یک API خدمات رمزنگاری ساده و سختافزاری داشت که توسط نسخههای 0.2 و 0.3 لایه انتزاعی سختافزار Keymaster (HAL) ارائه میشد. Keystore عملیات امضای دیجیتال و تأیید، به علاوه تولید و واردات جفت کلید امضای نامتقارن را ارائه میکرد. این در حال حاضر بر روی بسیاری از دستگاه ها اجرا شده است، اما اهداف امنیتی بسیاری وجود دارد که به راحتی تنها با یک API امضا نمی توان به آنها دست یافت. Android 6.0 Keystore API را گسترش داد تا طیف وسیع تری از قابلیت ها را ارائه دهد.
اندروید 6.0
در Android 6.0، Keymaster 1.0 رمزنگاری های اولیه متقارن ، AES و HMAC و یک سیستم کنترل دسترسی برای کلیدهای سخت افزاری را اضافه کرد. کنترل های دسترسی در طول تولید کلید مشخص می شوند و برای طول عمر کلید اجرا می شوند. کلیدها فقط پس از احراز هویت کاربر و فقط برای اهداف مشخص یا با پارامترهای رمزنگاری مشخص قابل استفاده هستند محدود شوند.
علاوه بر گسترش دامنه رمزنگاری اولیه، Keystore در Android 6.0 موارد زیر را اضافه کرد:
- یک طرح کنترل استفاده برای محدود کردن استفاده از کلید، برای کاهش خطر به خطر افتادن امنیت به دلیل استفاده نادرست از کلیدها
- یک طرح کنترل دسترسی برای فعال کردن محدودیت کلیدها برای کاربران مشخص، مشتریان، و محدوده زمانی تعریف شده
اندروید 7.0
در اندروید 7.0، Keymaster 2 پشتیبانی از گواهی کلید و اتصال نسخه را اضافه کرد.
تأیید کلید، گواهیهای کلید عمومی را ارائه میکند که حاوی شرح مفصلی از کلید و کنترلهای دسترسی آن است تا وجود کلید در سختافزار امن و پیکربندی آن از راه دور قابل تأیید باشد.
Version binding کلیدها را به سیستم عامل و نسخه سطح وصله متصل می کند. این تضمین میکند که مهاجمی که ضعفی را در نسخه قدیمی سیستم یا نرمافزار TEE کشف میکند، نمیتواند دستگاه را به نسخه آسیبپذیر برگرداند و از کلیدهای ایجاد شده با نسخه جدیدتر استفاده کند. علاوه بر این، هنگامی که کلیدی با یک نسخه معین و سطح وصله روی دستگاهی استفاده میشود که به نسخه جدیدتر یا سطح وصله ارتقا یافته است، کلید قبل از اینکه بتوان از آن استفاده کرد ارتقا داده میشود و نسخه قبلی کلید باطل میشود. با ارتقای دستگاه، کلیدها همراه با دستگاه به سمت جلو حرکت میکنند، اما هرگونه بازگشت دستگاه به نسخه قبلی باعث غیرقابل استفاده شدن کلیدها میشود.
اندروید 8.0
در اندروید 8.0، Keymaster 3 از ساختار قدیمی HAL به رابط C++ HAL که از تعریفی در زبان تعریف رابط سختافزاری جدید (HIDL) ایجاد شده بود، انتقال یافت. به عنوان بخشی از تغییر، بسیاری از انواع آرگومان ها تغییر کردند، اگرچه انواع و روش ها مطابقت یک به یک با انواع قدیمی و روش های ساختار HAL دارند.
علاوه بر این ویرایش رابط، Android 8.0 ویژگی تأیید Keymaster 2 را برای پشتیبانی از تأیید شناسه گسترش داد. گواهی شناسه مکانیزم محدود و اختیاری را برای تأیید قوی شناسه های سخت افزاری مانند شماره سریال دستگاه، نام محصول و شناسه تلفن (IMEI یا MEID) فراهم می کند. برای پیاده سازی این افزوده، Android 8.0 طرح گواهی ASN.1 را برای افزودن گواهی ID تغییر داد. پیادهسازیهای Keymaster باید راهی مطمئن برای بازیابی اقلام دادههای مربوطه و همچنین تعریف مکانیزمی برای غیرفعال کردن ایمن و دائمی این ویژگی پیدا کنند.
اندروید 9
در اندروید 9، به روز رسانی ها شامل:
- به روز رسانی به Keymaster 4
- پشتیبانی از عناصر امن جاسازی شده
- پشتیبانی از واردات کلید امن
- پشتیبانی از رمزگذاری 3DES
- تغییرات در binding نسخه به طوری که
boot.img
وsystem.img
به طور جداگانه نسخه هایی را تنظیم کرده اند تا امکان به روز رسانی مستقل را فراهم کنند.
اندروید 10
اندروید 10 نسخه 4.1 Keymaster HAL را معرفی کرد که اضافه کرد:
- پشتیبانی از کلیدهایی که فقط زمانی قابل استفاده هستند که قفل دستگاه باز است
- پشتیبانی از کلیدهایی که فقط در مراحل اولیه بوت قابل استفاده هستند
- پشتیبانی اختیاری از کلیدهای ذخیره سازی سخت افزاری
- پشتیبانی اختیاری برای گواهی منحصر به فرد دستگاه در StrongBox
اندروید 12
اندروید 12 KeyMint HAL جدید را معرفی کرد که جایگزین Keymaster HAL می شود اما عملکرد مشابهی را ارائه می دهد. علاوه بر تمام ویژگی های فوق، KeyMint HAL همچنین شامل موارد زیر است:
- پشتیبانی از قرارداد کلید ECDH
- پشتیبانی از کلیدهای تصدیق مشخص شده توسط کاربر
- پشتیبانی از کلیدهایی با تعداد کاربرد محدود
اندروید 12 همچنین شامل نسخه جدیدی از سیستم دیمون کیست استور است که در Rust بازنویسی شده و با نام keystore2
شناخته می شود.
اندروید 13
اندروید 13 نسخه 2 KeyMint HAL را اضافه کرد که پشتیبانی از Curve25519 را هم برای امضا و هم برای توافق کلید اضافه می کند.