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

شکل ۱. دسترسی به KeyMint.
رابط برنامهنویسی کاربردی KeyMint HAL سطح پایین است، توسط اجزای داخلی پلتفرم استفاده میشود و در دسترس توسعهدهندگان برنامه قرار ندارد. رابط برنامهنویسی کاربردی جاوا سطح بالاتر که برای برنامهها در دسترس است، در سایت توسعهدهندگان اندروید شرح داده شده است.
کنترل دسترسی
اندروید کیاستور یک جزء مرکزی برای ذخیرهسازی و استفاده از کلیدهای رمزنگاری سختافزاری، هم برای برنامهها و هم برای سایر اجزای سیستم، فراهم میکند. به این ترتیب، دسترسی به هر کلید منحصراً به برنامه یا جزء سیستمی که کلید را ایجاد کرده است، محدود میشود.
دامنههای کیاستور
برای پشتیبانی از این کنترل دسترسی، کلیدها با یک توصیفگر کلید به Keystore معرفی میشوند. این توصیفگر کلید، دامنهای را که توصیفگر به آن تعلق دارد، به همراه یک هویت در آن دامنه، نشان میدهد.
برنامههای اندروید با استفاده از معماری رمزنگاری استاندارد جاوا به Keystore دسترسی پیدا میکنند، که کلیدها را با یک نام مستعار رشتهای شناسایی میکند. این روش شناسایی به صورت داخلی به دامنه Keystore APP نگاشت میشود؛ UID فراخواننده نیز برای رفع ابهام کلیدها از برنامههای مختلف گنجانده شده است و از دسترسی یک برنامه به کلیدهای برنامه دیگر جلوگیری میکند.
در داخل، کد فریمورکها پس از بارگذاری یک کلید، یک شناسه کلید عددی منحصر به فرد نیز دریافت میکند. این شناسه عددی به عنوان شناسه برای توصیفگرهای کلید در دامنه KEY_ID استفاده میشود. با این حال، کنترل دسترسی همچنان انجام میشود: حتی اگر یک برنامه شناسه کلید را برای کلید برنامه دیگری کشف کند، نمیتواند در شرایط عادی از آن استفاده کند.
با این حال، یک برنامه میتواند اجازه استفاده از یک کلید را به برنامه دیگری (که توسط UID شناسایی میشود) بدهد. این عملیات اعطای مجوز، یک شناسه اعطای منحصر به فرد را برمیگرداند که به عنوان شناسه برای توصیفگرهای کلید در دامنه GRANT استفاده میشود. باز هم، کنترل دسترسی همچنان انجام میشود: حتی اگر برنامه سومی شناسه اعطای کلید یک دریافتکننده مجوز را کشف کند، نمیتواند از آن استفاده کند.
Keystore همچنین از دو دامنه دیگر برای توصیفگرهای کلید پشتیبانی میکند که برای سایر اجزای سیستم استفاده میشوند و برای کلیدهای ایجاد شده توسط برنامه در دسترس نیستند:
- دامنه
BLOBنشان میدهد که هیچ شناسهای برای کلید در توصیفگر کلید وجود ندارد؛ در عوض، توصیفگر کلید، خودِ keyblob را در خود نگه میدارد و کلاینت، ذخیرهسازی keyblob را مدیریت میکند. این دامنه توسط کلاینتهایی (برای مثال،vold) که نیاز به دسترسی به Keystore قبل از نصب پارتیشن داده دارند، استفاده میشود. - دامنه
SELINUXبه اجزای سیستم اجازه میدهد تا کلیدها را به اشتراک بگذارند، و دسترسی توسط یک شناسه عددی که مربوط به یک برچسب SELinux است، کنترل میشود ( برای keystore_key به سیاست SELinux مراجعه کنید).
سیاست SELinux برای keystore_key
مقادیر شناسه مورد استفاده برای توصیفگرهای کلید Domain::SELINUX در فایل سیاست SELinux keystore2_key_context پیکربندی شدهاند. هر خط در این فایلها یک عدد را به یک برچسب 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
کامپوننتی که نیاز به دسترسی به کلید با شناسه ۱۰۲ در دامنه SELINUX دارد، باید سیاست SELinux مربوطه را داشته باشد. برای مثال، برای اینکه به wpa_supplicant اجازه داده شود این کلیدها را دریافت و استفاده کند، خط زیر را به hal_wifi_supplicant.te اضافه کنید:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
شناسههای عددی برای کلیدهای Domain::SELINUX به محدودههایی تقسیم میشوند تا از پارتیشنهای مختلف بدون تداخل پشتیبانی کنند:
| پارتیشن | محدوده | فایلهای پیکربندی |
|---|---|---|
| سیستم | ۰ ... ۹,۹۹۹ | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
| سیستم توسعهیافته | ۱۰،۰۰۰ ... ۱۹،۹۹۹ | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
| محصول | ۲۰،۰۰۰ ... ۲۹۹۹۹ | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
| فروشنده | ۳۰،۰۰۰ ... ۳۹،۹۹۹ | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
مقادیر خاص زیر برای پارتیشن سیستم تعریف شدهاند:
| شناسه فضای نام | برچسب سیاست SE | شناسه کاربری | توضیحات |
|---|---|---|---|
| 0 | su_key | ناموجود | کلید کاربر ویژه. فقط برای آزمایش در نسخههای userdebug و eng استفاده میشود. در نسخههای user-bugg کاربردی ندارد. |
| ۱ | shell_key | ناموجود | فضای نام موجود برای پوسته. بیشتر برای آزمایش استفاده میشود، اما میتواند در نسخههای کاربری و همچنین از طریق خط فرمان مورد استفاده قرار گیرد. |
| ۱۰۰ | vold_key | ناموجود | برای استفاده توسط vold در نظر گرفته شده است. |
| ۱۰۱ | odsign_key | ناموجود | توسط سرویس امضای روی دستگاه استفاده میشود. |
| ۱۰۲ | wifi_key | AID_WIFI(1010) | توسط زیرسیستم وایفای اندروید از جمله wpa_supplicant استفاده میشود. |
| ۱۰۳ | locksettings_key | ناموجود | استفاده شده توسط LockSettingsService |
| ۱۲۰ | 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 | برای اطلاعرسانی به keystore مبنی بر قفل شدن دستگاه مورد نیاز است، که به نوبه خود super-keyها را حذف میکند تا اطمینان حاصل شود که کلیدهای مربوط به احراز هویت در دسترس نیستند. |
unlock | لازم است به keystore اطلاع داده شود که دستگاه قفلگشایی شده است و دسترسی به super-keyهایی که از کلیدهای مربوط به احراز هویت محافظت میکنند، بازیابی شود. |
reset | برای تنظیم مجدد Keystore به تنظیمات پیشفرض کارخانه و حذف تمام کلیدهایی که برای عملکرد سیستم عامل اندروید حیاتی نیستند، مورد نیاز است. |
تاریخچه
در اندروید ۵ و پایینتر، اندروید یک API ساده و مبتنی بر سختافزار برای خدمات رمزنگاری داشت که توسط نسخههای ۰.۲ و ۰.۳ لایه انتزاعی سختافزاری Keymaster (HAL) ارائه میشد. Keystore عملیات امضای دیجیتال و تأیید هویت، به علاوه تولید و وارد کردن جفت کلیدهای امضای نامتقارن را فراهم میکرد. این قابلیت در حال حاضر در بسیاری از دستگاهها پیادهسازی شده است، اما اهداف امنیتی زیادی وجود دارد که به راحتی نمیتوان تنها با یک API امضا به آنها دست یافت. اندروید ۶.۰ API Keystore را گسترش داد تا طیف وسیعتری از قابلیتها را ارائه دهد.
اندروید ۶.۰
در اندروید ۶.۰، Keymaster 1.0 اصول اولیه رمزنگاری متقارن ، AES و HMAC و یک سیستم کنترل دسترسی برای کلیدهای سختافزاری را اضافه کرد. کنترلهای دسترسی در طول تولید کلید مشخص شده و در طول عمر کلید اعمال میشوند. کلیدها را میتوان محدود کرد تا فقط پس از احراز هویت کاربر و فقط برای اهداف مشخص یا با پارامترهای رمزنگاری مشخص، قابل استفاده باشند.
علاوه بر گسترش دامنهی اصول رمزنگاری، Keystore در اندروید ۶.۰ موارد زیر را نیز اضافه کرده است:
- یک طرح کنترل استفاده برای محدود کردن استفاده از کلید، به منظور کاهش خطر به خطر افتادن امنیت به دلیل سوءاستفاده از کلیدها
- یک طرح کنترل دسترسی برای محدود کردن کلیدها به کاربران، کلاینتهای مشخص و یک محدوده زمانی تعریفشده
اندروید ۷.۰
در اندروید ۷.۰، Keymaster 2 پشتیبانی از گواهی کلید و اتصال نسخه را اضافه کرد.
تأیید کلید، گواهیهای کلید عمومی را ارائه میدهد که شامل شرح مفصلی از کلید و کنترلهای دسترسی آن است تا وجود کلید در سختافزار امن و پیکربندی آن از راه دور قابل تأیید باشد.
اتصال نسخه، کلیدها را به سیستم عامل و نسخه سطح وصله (patch level) متصل میکند. این تضمین میکند که مهاجمی که ضعفی را در نسخه قدیمی سیستم یا نرمافزار TEE کشف میکند، نمیتواند دستگاه را به نسخه آسیبپذیر برگرداند و از کلیدهای ایجاد شده با نسخه جدیدتر استفاده کند. علاوه بر این، هنگامی که یک کلید با نسخه و سطح وصله مشخص در دستگاهی که به نسخه جدیدتر یا سطح وصله ارتقا یافته است استفاده میشود، کلید قبل از استفاده ارتقا مییابد و نسخه قبلی کلید نامعتبر میشود. با ارتقا دستگاه، کلیدها همراه با دستگاه به جلو حرکت میکنند، اما هرگونه بازگشت دستگاه به نسخه قبلی باعث میشود که کلیدها غیرقابل استفاده شوند.
اندروید ۸.۰
در اندروید ۸.۰، Keymaster 3 از ساختار قدیمی HAL به زبان C++ HAL که از تعریفی در زبان تعریف رابط سختافزاری جدید (HIDL) تولید شده بود، تغییر کرد. به عنوان بخشی از این تغییر، بسیاری از انواع آرگومانها تغییر کردند، اگرچه انواع و روشها با انواع قدیمی و روشهای ساختار HAL تناظر یک به یک دارند.
علاوه بر این اصلاح رابط کاربری، اندروید ۸.۰ ویژگی گواهی Keymaster 2 را برای پشتیبانی از گواهی ID گسترش داد. گواهی ID یک مکانیسم محدود و اختیاری برای گواهی قوی شناسههای سختافزاری، مانند شماره سریال دستگاه، نام محصول و شناسه تلفن (IMEI یا MEID) فراهم میکند. برای پیادهسازی این قابلیت، اندروید ۸.۰ طرح گواهی ASN.1 را تغییر داد تا گواهی ID را اضافه کند. پیادهسازیهای Keymaster باید راهی امن برای بازیابی اقلام داده مربوطه و همچنین تعریف مکانیسمی برای غیرفعال کردن ایمن و دائمی این ویژگی پیدا کنند.
اندروید ۹
در اندروید ۹، بهروزرسانیها شامل موارد زیر بودند:
- بهروزرسانی به کیمستر ۴
- پشتیبانی از عناصر امنیتی تعبیهشده
- پشتیبانی از وارد کردن کلید امن
- پشتیبانی از رمزگذاری 3DES
- تغییرات در اتصال نسخه به طوری که
boot.imgوsystem.imgنسخههای جداگانهای دارند تا بهروزرسانیهای مستقل امکانپذیر باشد.
اندروید ۱۰
اندروید ۱۰ نسخه ۴.۱ از Keymaster HAL را معرفی کرد که موارد زیر را اضافه کرد:
- پشتیبانی از کلیدهایی که فقط هنگام باز شدن قفل دستگاه قابل استفاده هستند
- پشتیبانی از کلیدهایی که فقط در مراحل اولیه بوت قابل استفاده هستند
- پشتیبانی اختیاری برای کلیدهای ذخیرهسازی سختافزاری
- پشتیبانی اختیاری برای گواهی منحصر به فرد دستگاه در StrongBox
اندروید ۱۲
اندروید ۱۲، KeyMint HAL جدید را معرفی کرد که جایگزین Keymaster HAL شده اما عملکرد مشابهی را ارائه میدهد. علاوه بر تمام ویژگیهای فوق، KeyMint HAL شامل موارد زیر نیز میشود:
- پشتیبانی از توافقنامه کلید ECDH
- پشتیبانی از کلیدهای تأیید هویت مشخص شده توسط کاربر
- Supoprt برای کلیدهایی با تعداد استفاده محدود
اندروید ۱۲ همچنین شامل نسخه جدیدی از دیمن سیستم keystore است که با زبان Rust بازنویسی شده و با نام keystore2 شناخته میشود.
اندروید ۱۳
اندروید ۱۳ نسخه ۲ از KeyMint HAL را اضافه کرد که پشتیبانی از Curve25519 را هم برای امضا و هم برای توافق کلید اضافه میکند.