گواهی کلید و شناسه

Keystore مکان امن تری را برای ایجاد، ذخیره و استفاده از کلیدهای رمزنگاری به روشی کنترل شده فراهم می کند. هنگامی که ذخیره‌سازی کلید با پشتوانه سخت‌افزاری در دسترس است و استفاده می‌شود، مواد کلید در برابر استخراج از دستگاه ایمن‌تر هستند و Keymaster محدودیت‌هایی را اعمال می‌کند که به سختی می‌توان آن‌ها را برانداز کرد.

با این حال، این تنها در صورتی صادق است که کلیدهای ذخیره‌سازی کلید در فضای ذخیره‌سازی سخت‌افزاری قرار داشته باشند. در Keymaster 1، هیچ راهی برای برنامه ها یا سرورهای راه دور وجود نداشت که به طور قابل اعتماد تأیید کنند که آیا چنین است. دیمون keystore، keymaster موجود HAL را بارگذاری کرد و هر آنچه که HAL در رابطه با پشتوانه سخت افزاری کلیدها می گفت، باور داشت.

برای رفع این مشکل، Keymaster گواهینامه کلید را در Android 7.0 (Keymaster 2) و گواهی ID را در Android 8.0 (Keymaster 3) معرفی کرد.

هدف تأیید کلید ارائه راهی برای تعیین قویاً تعیین اینکه آیا یک جفت کلید نامتقارن دارای پشتوانه سخت افزاری است، ویژگی های کلید چیست و چه محدودیت هایی برای استفاده از آن اعمال می شود.

گواهی شناسه به دستگاه اجازه می دهد تا مدرک شناسایی سخت افزاری خود، مانند شماره سریال یا IMEI را ارائه دهد.

گواهی کلیدی

برای پشتیبانی از گواهی کلید، اندروید 7.1 مجموعه ای از برچسب ها، نوع و روش را به HAL معرفی کرد.

برچسب ها

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

تایپ کنید

Keymaster 2 و پایین تر

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

روش AttestKey

کی مستر 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 و پایین تر

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev ساختار دستگاه کی مستر است.
  • keyToAttest حباب کلیدی است که از generateKey بازگردانده می شود و گواهی برای آن ایجاد می شود.
  • attestParams لیستی از پارامترهای لازم برای تأیید است. این شامل Tag::ATTESTATION_CHALLENGE و احتمالاً Tag::RESET_SINCE_ID_ROTATION ، و همچنین Tag::APPLICATION_ID و Tag::APPLICATION_DATA است. دو مورد آخر برای رمزگشایی حباب کلید در صورتی که در طول تولید کلید مشخص شده باشند، ضروری هستند.
  • certChain پارامتر خروجی است که آرایه ای از گواهی ها را برمی گرداند. ورودی 0 گواهی گواهی است، به این معنی که کلید را از keyToAttest تأیید می کند و حاوی پسوند گواهی است.

متد attestKey یک عملیات کلید عمومی روی کلید تایید شده در نظر گرفته می شود، زیرا می توان آن را در هر زمان فراخوانی کرد و نیازی به رعایت محدودیت های مجوز ندارد. به عنوان مثال، اگر کلید تأیید شده برای استفاده نیاز به احراز هویت کاربر داشته باشد، می‌توان بدون احراز هویت کاربر، یک تأییدیه تولید کرد.

گواهی تصدیق

گواهی تأیید یک گواهی استاندارد X.509 با پسوند گواهی اختیاری است که حاوی توضیحات کلید تأیید شده است. این گواهی با یک کلید گواهی تایید شده امضا شده است. کلید تأیید ممکن است از الگوریتم متفاوتی نسبت به کلید تأیید شده استفاده کند.

گواهی گواهی شامل فیلدهای جدول زیر است و نمی تواند حاوی فیلدهای اضافی باشد. برخی از فیلدها مقدار فیلد ثابتی را مشخص می کنند. آزمون‌های CTS تأیید می‌کنند که محتوای گواهی دقیقاً مطابق تعریف است.

SEQUENCE گواهی

نام فیلد (به RFC 5280 مراجعه کنید) ارزش
گواهی tbs SEQUENCE گواهی TBSC
الگوریتم امضا AlgorithmIdentifier الگوریتم مورد استفاده برای علامت گذاری کلید:
ECDSA برای کلیدهای EC، RSA برای کلیدهای RSA.
signatureValue BIT STRING، امضای محاسبه شده در ASN.1 DER-encoded tbsCertificate.

SEQUENCE گواهی TBSC

نام فیلد (به RFC 5280 مراجعه کنید) ارزش
version INTEGER 2 (به معنای گواهی v3)
serialNumber INTEGER 1 (مقدار ثابت: در همه گواهی ها یکسان است)
signature AlgorithmIdentifier الگوریتم مورد استفاده برای علامت گذاری کلید: ECDSA برای کلیدهای EC، RSA برای کلیدهای RSA.
issuer مانند فیلد موضوع کلید تأیید دسته ای.
validity SEQUENCE از دو تاریخ، حاوی مقادیر Tag::ACTIVE_DATETIME و Tag::USAGE_EXPIRE_DATETIME . این مقادیر از 1 ژانویه 1970 بر حسب میلی ثانیه هستند. برای نمایش صحیح تاریخ در گواهی ها به RFC 5280 مراجعه کنید.
اگر Tag::ACTIVE_DATETIME وجود ندارد، از مقدار Tag::CREATION_DATETIME استفاده کنید. اگر Tag::USAGE_EXPIRE_DATETIME وجود ندارد، از تاریخ انقضای گواهی کلید تأیید دسته استفاده کنید.
subject CN = "Android Keystore Key" (مقدار ثابت: در همه گواهی ها یکسان است)
subjectPublicKeyInfo SubjectPublicKeyInfo حاوی کلید عمومی تایید شده.
extensions/Key Usage DigitalSignature: تنظیم کنید که آیا کلید هدفی دارد KeyPurpose::SIGN یا KeyPurpose::VERIFY . همه بیت های دیگر تنظیم نشده است.
extensions/CRL Distribution Points ارزش TBD
extensions/"attestation" OID 1.3.6.1.4.1.11129.2.1.17 است. محتوا در بخش پسوند گواهی در زیر تعریف شده است. مانند تمام پسوندهای گواهی X.509، محتوا به صورت OCTET_STRING حاوی رمزگذاری DER از SEQUENCE گواهی نمایش داده می شود.

تمدید تصدیق

برنامه افزودنی attestation شامل شرح کاملی از مجوزهای keymaster مرتبط با کلید است، در ساختاری که مستقیماً با لیست های مجوز استفاده شده در Android و keymaster HAL مطابقت دارد. هر تگ در یک لیست مجوز با یک ورودی ASN.1 SEQUENCE نشان داده می شود که به صراحت با شماره تگ keymaster برچسب گذاری شده است، اما توصیفگر نوع (چهار بیت مرتبه بالا) پوشانده شده است.

برای مثال، در Keymaster 3، Tag::PURPOSE در Types.hal به صورت ENUM_REP | 1 . برای پسوند گواهی، مقدار ENUM_REP حذف می‌شود و برچسب 1 باقی می‌ماند. (برای Keymaster 2 و پایین تر، KM_TAG_PURPOSE در keymaster_defs.h تعریف شده است.)

مقادیر در این جدول به روشی ساده به انواع ASN.1 ترجمه می شوند:

نوع Keymaster نوع ASN.1
ENUM عدد صحیح
ENUM_REP SET از INTEGER
UINT عدد صحیح
UINT_REP SET از INTEGER
ULONG عدد صحیح
ULONG_REP SET از INTEGER
DATE INTEGER (میلی ثانیه از 1 ژانویه 1970 00:00:00 GMT)
BOOL NULL (در keymaster، tag present به معنای درست، absent به معنای نادرست است.
همان معناشناسی برای رمزگذاری ASN.1 اعمال می شود)
BIGNUM در حال حاضر استفاده نمی شود، بنابراین هیچ نقشه برداری تعریف نشده است
BYTES OCTET_STRING

طرحواره

محتوای پسوند گواهی با طرح ASN.1 زیر توضیح داده شده است.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

فیلدهای توصیف کلید

فیلدهای keymasterVersion و attestationChallenge به جای برچسب، به صورت موقعیتی شناسایی می شوند، بنابراین برچسب ها در فرم کدگذاری شده فقط نوع فیلد را مشخص می کنند. فیلدهای باقی مانده به طور ضمنی همانطور که در طرح مشخص شده است برچسب گذاری می شوند.

نام زمینه تایپ کنید ارزش
attestationVersion عدد صحیح نسخه طرحواره تصدیق: 1، 2، یا 3.
attestationSecurity سطح امنیت سطح امنیتی این گواهی. دریافت گواهی نرم افزاری کلیدهای سخت افزاری امکان پذیر است. اگر سیستم اندروید به خطر بیفتد نمی توان به چنین گواهی هایی اعتماد کرد.
keymasterVersion عدد صحیح نسخه کی مستر دستگاه: 0، 1، 2، 3 یا 4.
keymasterSecurity سطح امنیت سطح امنیتی اجرای کی مستر
attestationChallenge OCTET_STRING مقدار Tag::ATTESTATION_CHALLENGE ، برای درخواست گواهی مشخص شده است.
uniqueId OCTET_STRING شناسه منحصر به فرد اختیاری، اگر کلید دارای Tag::INCLUDE_UNIQUE_ID باشد، وجود دارد
softwareEnforced لیست مجوز مجوزهای اختیاری، keymaster که در صورت وجود توسط TEE اجرا نمی شوند.
teeEnforced لیست مجوز اختیاری، مجوزهای Keymaster که توسط TEE اجرا می شود، در صورت وجود.

فیلدهای AuthorizationList

فیلدهای AuthorizationList همگی اختیاری هستند و با مقدار تگ keymaster مشخص می شوند و نوع بیت ها پنهان شده اند. از برچسب‌گذاری صریح استفاده می‌شود، بنابراین فیلدها همچنین حاوی برچسبی هستند که نوع ASN.1 آنها را نشان می‌دهد تا تجزیه آسان‌تر شود.

برای جزئیات بیشتر در مورد مقادیر هر فیلد، به types.hal برای Keymaster 3 و keymaster_defs.h برای Keymaster 2 و زیر مراجعه کنید. نام‌های تگ Keymaster با حذف پیشوند KM_TAG و تغییر باقی‌مانده به casem به نام فیلد تبدیل شدند، بنابراین Tag::KEY_SIZE تبدیل به keySize شد.

فیلدهای RootOfTrust

فیلدهای RootOfTrust به صورت موقعیتی شناسایی می شوند.

نام زمینه تایپ کنید ارزش
verifiedBootKey OCTET_STRING هش امن کلید مورد استفاده برای تأیید تصویر سیستم. SHA-256 توصیه می شود.
deviceLocked بولین درست است اگر بوت لودر قفل باشد، به این معنی که فقط تصاویر امضا شده را می توان فلش کرد و بررسی بوت تایید شده انجام می شود.
verifiedBootState VerifiedBootState وضعیت بوت تایید شده
verifiedBootHash OCTET_STRING خلاصه ای از تمام داده های محافظت شده توسط Verified Boot. برای دستگاه‌هایی که از اجرای Android Verified Boot از Verified Boot استفاده می‌کنند، این مقدار حاوی خلاصه ساختار VBMeta یا ساختار فراداده Verified Boot است. برای کسب اطلاعات بیشتر در مورد نحوه محاسبه این مقدار، بهThe VBMeta Digest مراجعه کنید

مقادیر VerifiedBootState

مقادیر verifiedBootState معانی زیر را دارند:

ارزش معنی
Verified نشان‌دهنده یک زنجیره کامل از اعتماد است که از بوت‌لودر تا پارتیشن‌های تایید شده، از جمله بوت‌لودر، پارتیشن بوت، و همه پارتیشن‌های تایید شده گسترش می‌یابد.
در این حالت، مقدار verifiedBootKey هش گواهی جاسازی شده است، به این معنی که گواهی غیرقابل تغییر در ROM رایت شده است.
این حالت با حالت بوت سبز مطابق با مستندات جریان بوت تأیید شده مطابقت دارد.
SelfSigned نشان می دهد که پارتیشن بوت با استفاده از گواهی تعبیه شده تأیید شده است و امضا معتبر است. بوت لودر یک هشدار و اثر انگشت کلید عمومی را قبل از ادامه فرآیند بوت نمایش می دهد.
در این حالت، مقدار verifiedBootKey هش گواهی خود امضا است.
این حالت با حالت بوت زرد مطابق با مستندات جریان بوت تأیید شده مطابقت دارد.
Unverified نشان می دهد که یک دستگاه ممکن است آزادانه تغییر یابد. یکپارچگی دستگاه برای تأیید خارج از باند به کاربر واگذار می شود. بوت لودر قبل از ادامه فرآیند بوت، هشداری را به کاربر نمایش می دهد.
در این حالت مقدار verifiedBootKey خالی است.
این حالت مطابق با حالت بوت نارنجی است که در مستندات جریان بوت تأیید شده مستند شده است.
Failed نشان می دهد که دستگاه تأیید نشده است. هیچ گواهی گواهی در واقع حاوی این مقدار نیست، زیرا در این حالت بوت لودر متوقف می شود. برای کامل بودن در اینجا گنجانده شده است.
این حالت با حالت بوت قرمز مطابق با مستندات جریان بوت تأیید شده مطابقت دارد.

مقادیر SecurityLevel

مقادیر securityLevel معانی زیر را دارند:

ارزش معنی
Software کدی که عنصر مربوطه (تأیید یا کلید) را ایجاد یا مدیریت می کند در سیستم اندروید پیاده سازی می شود و در صورت به خطر افتادن آن سیستم می تواند تغییر یابد.
TrustedEnvironment کدی که عنصر مربوطه (تأیید یا کلید) را ایجاد یا مدیریت می کند در یک محیط اجرای مورد اعتماد (TEE) پیاده سازی می شود. اگر TEE در معرض خطر قرار گیرد، می‌توان آن را تغییر داد، اما TEE در برابر نفوذ از راه دور بسیار مقاوم است و در برابر حمله مستقیم سخت‌افزاری نسبتاً مقاوم است.
StrongBox کدی که عنصر مربوطه (تأیید یا کلید) را ایجاد یا مدیریت می کند در یک ماژول امنیتی سخت افزاری اختصاصی پیاده سازی می شود. اگر ماژول امنیتی سخت‌افزار به خطر بیفتد، می‌توان آن را تغییر داد، اما در برابر نفوذ از راه دور بسیار مقاوم است و در برابر حمله مستقیم سخت‌افزاری بسیار مقاوم است.

شناسه منحصر به فرد

شناسه منحصر به فرد یک مقدار 128 بیتی است که دستگاه را شناسایی می کند، اما فقط برای مدت زمان محدود. مقدار با:

HMAC_SHA256(T || C || R, HBK)

جایی که:

  • T "مقدار شمارشگر زمانی" است که با تقسیم مقدار Tag::CREATION_DATETIME بر 2592000000 محاسبه می شود و باقی مانده را حذف می کند. T هر 30 روز تغییر می کند (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C مقدار Tag::APPLICATION_ID است
  • اگر Tag::RESET_SINCE_ID_ROTATION در پارامتر attest_params برای فراخوانی attest_key وجود داشته باشد، R برابر 1 است، یا اگر برچسب وجود نداشته باشد، 0 است.
  • HBK یک راز منحصربفرد سخت افزاری است که توسط Trusted Execution Environment شناخته شده و هرگز توسط آن فاش نشده است. راز حاوی حداقل 128 بیت آنتروپی است و برای هر دستگاه منحصر به فرد است (یکتایی احتمالی با توجه به 128 بیت آنتروپی قابل قبول است). HBK باید از مواد کلید ذوب شده از طریق HMAC یا AES_CMAC مشتق شود.

خروجی HMAC_SHA256 را به 128 بیت کوتاه کنید.

کلیدهای تصدیق و گواهی

دو کلید، یک RSA و یک ECDSA، و زنجیره های گواهی مربوطه، به طور ایمن در دستگاه قرار داده شده اند.

Android 12 Remote Key Provisioning را معرفی می‌کند و Android 13 نیازمند اجرای آن توسط دستگاه‌ها است. Remote Key Provisioning دستگاه هایی را در این زمینه با گواهی گواهی ECDSA P256 برای هر برنامه ارائه می دهد. این گواهی ها نسبت به گواهی های ارائه شده در کارخانه عمر کوتاه تری دارند.

چندین IMEI

اندروید 14 پشتیبانی از چندین IMEI را در رکورد تأیید کلید اندروید اضافه می کند. OEM ها می توانند این ویژگی را با افزودن یک تگ KeyMint برای IMEI دوم پیاده سازی کنند. به طور فزاینده ای رایج می شود که دستگاه ها چندین رادیو سلولی داشته باشند و OEM ها اکنون می توانند دستگاه هایی با دو IMEI را پشتیبانی کنند.

OEM ها ملزم به داشتن یک IMEI ثانویه هستند، در صورت وجود در دستگاه هایشان، به پیاده سازی(های) KeyMint ارائه شود تا این پیاده سازی ها بتوانند آن را به همان روشی که به IMEI اول تأیید می کنند، تأیید کنند.

گواهی شناسایی

Android 8.0 شامل پشتیبانی اختیاری برای تأیید شناسه برای دستگاه‌های دارای Keymaster 3 می‌شود. تأیید ID به دستگاه اجازه می‌دهد تا مدرک شناسایی سخت‌افزاری خود، مانند شماره سریال یا IMEI را ارائه دهد. اگرچه یک ویژگی اختیاری است، اما به شدت توصیه می‌شود که همه پیاده‌سازی‌های Keymaster 3 از آن پشتیبانی کنند، زیرا توانایی اثبات هویت دستگاه، موارد استفاده مانند پیکربندی کنترل از راه دور صفر لمسی را ایمن‌تر می‌سازد (زیرا سمت راه دور می‌تواند از آن مطمئن باشد. با دستگاه مناسب صحبت می کند، نه دستگاهی که هویت آن را جعل می کند).

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

سطح اصلی API برای تأیید ID بر روی مکانیزم تأیید کلید موجود معرفی شده با Keymaster 2 ساخته می شود. هنگام درخواست گواهی تأیید برای کلیدی که توسط keymaster نگهداری می شود، تماس گیرنده ممکن است درخواست کند که شناسه های سخت افزاری دستگاه در فراداده گواهی تأیید گنجانده شود. اگر کلید در TEE نگه داشته شود، گواهی به یک ریشه شناخته شده اعتماد زنجیر می شود. گیرنده چنین گواهی می تواند تأیید کند که گواهی و محتویات آن، از جمله شناسه های سخت افزاری، توسط TEE نوشته شده است. وقتی از TEE خواسته می‌شود که شناسه‌های سخت‌افزاری را در گواهی تصدیق لحاظ کند، تنها شناسه‌هایی را که در انبارش نگهداری می‌شود، همانطور که در طبقه کارخانه جمع‌آوری شده است، تأیید می‌کند.

خواص ذخیره سازی

فضای ذخیره‌سازی که شناسه‌های دستگاه را در خود جای می‌دهد باید این ویژگی‌ها را داشته باشد:

  • مقادیر به دست آمده از شناسه های اصلی دستگاه قبل از خروج دستگاه از کارخانه در حافظه کپی می شود.
  • متد destroyAttestationIds() می تواند این کپی از داده های مشتق شده از شناسه را برای همیشه از بین ببرد. تخریب دائمی به این معنی است که داده ها به طور کامل حذف می شوند، بنابراین نه بازنشانی کارخانه ای و نه هیچ روش دیگری که روی دستگاه انجام شده است نمی تواند آن را بازیابی کند. این به ویژه برای دستگاه‌هایی که کاربر بوت لودر را باز کرده و نرم‌افزار سیستم را تغییر داده و شناسه‌های بازگردانده شده توسط فریمورک‌های اندروید را تغییر داده است، بسیار مهم است.
  • امکانات RMA باید توانایی تولید کپی های تازه از داده های مشتق شده از شناسه سخت افزار را داشته باشند. به این ترتیب، دستگاهی که از RMA عبور می کند می تواند دوباره گواهی ID را انجام دهد. مکانیسم مورد استفاده توسط تسهیلات RMA باید محافظت شود تا کاربران نتوانند خودشان آن را فراخوانی کنند، زیرا این امکان را به آنها می دهد تا گواهی شناسه های جعلی را دریافت کنند.
  • هیچ کد دیگری به جز برنامه قابل اعتماد Keymaster در TEE قادر به خواندن داده های مشتق شده از شناسه نگهداری شده در حافظه نیست.
  • ذخیره‌سازی غیرقابل دستکاری است: اگر محتوای ذخیره‌سازی اصلاح شده باشد، TEE با آن به‌گونه‌ای برخورد می‌کند که گویی کپی‌های محتوا از بین رفته‌اند و تمام تلاش‌های تأیید هویت را رد می‌کند. این کار با امضا کردن یا MAC کردن فضای ذخیره سازی همانطور که در زیر توضیح داده شده است اجرا می شود.
  • ذخیره سازی شناسه های اصلی را نگه نمی دارد. از آنجا که تأیید شناسه شامل یک چالش است، تماس گیرنده همیشه شناسه هایی را که باید تأیید شوند را ارائه می دهد. TEE فقط باید تأیید کند که این مقادیر با مقادیر اولیه مطابقت دارند. ذخیره هش های ایمن مقادیر اصلی به جای مقادیر، این تأیید را فعال می کند.

ساخت و ساز

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

S = D || HMAC(HBK, D)

جایی که:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC ساختار HMAC با هش امن مناسب است (SHA-256 توصیه می شود)
  • HBK یک کلید سخت افزاری است که برای هیچ هدف دیگری استفاده نمی شود
  • ID 1 ...ID n مقادیر ID اصلی هستند. ارتباط یک مقدار خاص با یک شاخص خاص وابسته به پیاده سازی است، زیرا دستگاه های مختلف تعداد شناسه های متفاوتی خواهند داشت.
  • || نشان دهنده الحاق است

از آنجایی که خروجی‌های HMAC اندازه ثابتی دارند، هیچ هدر یا ساختار دیگری برای یافتن هش‌های ID یا HMAC از D لازم نیست. علاوه بر بررسی مقادیر ارائه‌شده برای انجام تأیید، پیاده‌سازی‌ها باید S را با استخراج D از S تأیید کنند. ، محاسبه HMAC(HBK, D) و مقایسه آن با مقدار S برای تأیید اینکه هیچ شناسه فردی تغییر یا خراب نشده است. همچنین، پیاده‌سازی‌ها باید از مقایسه‌های زمان ثابت برای همه عناصر ID استفاده کنند و اعتبار S. زمان مقایسه باید بدون توجه به تعداد شناسه‌های ارائه‌شده و تطابق صحیح هر بخش از آزمون ثابت باشد.

شناسه های سخت افزاری

گواهی شناسه از شناسه های سخت افزاری زیر پشتیبانی می کند:

  1. نام تجاری، همانطور که توسط Build.BRAND در Android برگردانده شده است
  2. نام دستگاه، همانطور که توسط Build.DEVICE در Android برگردانده شده است
  3. نام محصول، همانطور که توسط Build.PRODUCT در Android بازگردانده شده است
  4. نام سازنده، همانطور که Build.MANUFACTURER در Android برگردانده است
  5. نام مدل، همانطور که توسط Build.MODEL در Android برگردانده شده است
  6. شماره سریال
  7. IMEI همه رادیوها
  8. MEID همه رادیوها

برای پشتیبانی از گواهی شناسه دستگاه، دستگاهی این شناسه ها را تأیید می کند. همه دستگاه های دارای اندروید دارای شش مورد اول هستند و برای کارکرد این ویژگی ضروری هستند. اگر دستگاه دارای رادیوهای سلولی یکپارچه باشد، دستگاه باید از گواهی IMEI و/یا MEID رادیوها نیز پشتیبانی کند.

تأیید شناسه با انجام تأییدیه کلید و گنجاندن شناسه های دستگاه برای تأیید در درخواست درخواست می شود. شناسه ها به صورت زیر برچسب گذاری می شوند:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

شناسه ای که باید تأیید شود یک رشته بایت کدگذاری شده UTF-8 است. این قالب برای شناسه های عددی نیز اعمال می شود. هر شناسه ای که باید تأیید شود به عنوان یک رشته رمزگذاری شده UTF-8 بیان می شود.

اگر دستگاه از تأیید شناسه پشتیبانی نمی‌کند (یا قبلاً فراخوانی شده بود destroyAttestationIds() و دستگاه دیگر نمی‌تواند شناسه‌های خود را تأیید کند)، هر درخواست تأییدیه کلیدی که شامل یک یا چند مورد از این برچسب‌ها باشد با ErrorCode::CANNOT_ATTEST_IDS با شکست مواجه می‌شود.

اگر دستگاه از تأیید شناسه پشتیبانی می کند و یک یا چند تگ فوق در درخواست تأیید کلید گنجانده شده باشد، TEE تأیید می کند که شناسه ارائه شده با هر یک از برچسب ها با کپی شناسه های سخت افزاری آن مطابقت دارد. اگر یک یا چند شناسه مطابقت نداشته باشند، کل تأییدیه با ErrorCode::CANNOT_ATTEST_IDS ناموفق است. این برای یک برچسب معتبر است که چندین بار عرضه شود. این می تواند برای مثال هنگام تأیید IMEI مفید باشد: یک دستگاه ممکن است چندین رادیو با چندین IMEI داشته باشد. اگر مقدار ارائه شده با هر ATTESTATION_ID_IMEI با یکی از رادیوهای دستگاه مطابقت داشته باشد، درخواست تأیید معتبر است. همین امر در مورد سایر برچسب ها نیز صدق می کند.

در صورت موفقیت آمیز بودن تأیید، شناسه های تأیید شده با استفاده از طرحواره بالا به پسوند گواهی (OID 1.3.6.1.4.1.11129.2.1.17) گواهی گواهی صادر شده اضافه می شود. تغییرات طرحواره گواهی Keymaster 2 پررنگ ، همراه با نظرات است.

Java API

این بخش فقط اطلاعاتی است. پیاده‌سازهای Keymaster نه API جاوا را پیاده‌سازی می‌کنند و نه استفاده می‌کنند. این برای کمک به پیاده‌سازان برای درک نحوه استفاده از این ویژگی توسط برنامه‌ها ارائه شده است. اجزای سیستم ممکن است متفاوت از آن استفاده کنند، به همین دلیل است که بسیار مهم است که این بخش به عنوان هنجاری در نظر گرفته نشود.