מדריך מעשי למאגר האישורים ב-Windows — משתמש או מחשב, לאן שמים

· · אישורים, Windows, אבטחה, PKI, TLS, PowerShell, יישומים עסקיים, מערכות מידע

«בעדכון המחשב לאימות זכאות מקוון הכנסנו מחדש אישור לקוח למחשב החדש, והחיבור נקטע», «במכונת הפיתוח מתחברים ל-API של הבנק, וכשהפכנו לשירות Windows מתקבל «האישור לא נמצא»», «מלכתחילה לא ברור מי האמיתי — האישור שרואים ב-certmgr.msc או זה שרואים ב-certlm.msc» — כשעושים בפיתוח תוכנה בהתאמה שילוב Web API עם אישור לקוח, ייעוץ מהסוג הזה מגיע באופן קבוע.

אימות זכאות מקוון במוסדות רפואיים, הגשה אלקטרונית, API בנקאי, EDI מול שותפים. אישורי לקוח, שפעם נגעו בהם רק אנשי תשתית בארגונים גדולים, הם היום עניין לאנשי מערכות מידע בעסקים קטנים ובינוניים ולמפתחי יישומים עסקיים. ותאונות סביב אישורים מתכנסות בפועל לכמה דפוסים. שמים במקום הלא נכון, שוכחים הרשאות למפתח הפרטי, שוכחים תוקף — שלושת אלה.

המאמר הזה מיועד למפתחי יישומים עסקיים שמשתמשים באישור לקוח, ולאנשי מערכות מידע שמקבלים על עצמם החלפת אישורים. סביב ההחלטה «לשים במאגר המשתמש או במאגר המחשב» הוא מסדר בבת אחת את מבנה מאגר האישורים ב-Windows, הענקת הרשאות למפתח הפרטי, ספירת תוקף ב-PowerShell, וקוד שימוש מ-.NET. התוכן מבוסס על מקורות ראשוניים של Microsoft Learn נכון לאוגוסט 2026.

1. השורה התחתונה קודם

  • למאגר האישורים ב-Windows יש שני קווים: «משתמש (CurrentUser)» ו«מחשב (LocalMachine)». מאגר המשתמש שונה לכל חשבון (תחת HKEY_CURRENT_USER ברישום), ומאגר המחשב משותף לכל המחשב (תחת HKEY_LOCAL_MACHINE).12
  • יש גם שני כלי ניהול. certmgr.msc פותח את מאגר המשתמש הנוכחי, certlm.msc את מאגר המחשב המקומי. מ-PowerShell זה Cert:\CurrentUser ו-Cert:\LocalMachine.34
  • לאן שמים נקבע לפי «כמי רצה התוכנית שמשתמשת באישור». ביישום של משתמש אינטראקטיבי — מאגר המשתמש; בהרצה בלי פיקוח של שירות Windows, IIS או Task Scheduler — ככלל מאגר המחשב (טבלת ההחלטה בפרק 3).
  • הסיבה ל«בפיתוח עבד, ובהפיכה לשירות לא נמצא» כמעט תמיד אחת. אישור שמפתח שם במאגר המשתמש שלו אינו נראה מ-CurrentUser של שירות שרץ בחשבון אחר (פרק 3).
  • אישור ומפתח פרטי הם דבר שונה. עצם השמה במאגר המחשב אינה אומרת שחשבון השירות יכול לקרוא את המפתח הפרטי. מעניקים הרשאת קריאה לחשבון ההרצה ב«ניהול מפתחות פרטיים» ב-certlm.msc.5
  • בייבוא pfx, המפתח הפרטי כברירת מחדל אינו ניתן לייצוא. Import-PfxCertificate מייבא כך שאי אפשר לייצא מחדש את המפתח הפרטי אלא אם מציינים -Exportable. זו לא תאונה; זו ברירת מחדל רצויה.6
  • פקיעת תוקף מונעים באוטומציית ספירה. אפשר לשלוף באופן מכני אישורים שיפקעו בתוך מספר ימים שצוין, כמו Get-ChildItem Cert:\LocalMachine\My -ExpiringInDays 60.4
  • קיבוע טביעת אצבע (thumbprint) בקוד או בתצורה מת, בכל עדכון אישור. לאישור חדש תמיד יש טביעת אצבע אחרת. הבסיס בתכנון הוא הוצאה לתצורה + תקופת מקביליות של ישן וחדש (פרקים 5 ו-7).

מפת הידע של המאמר

למאגר האישורים ב-Windows שני קווים, משתמש (CurrentUser) ומחשב (LocalMachine), ולאן לשים אישור לקוח נקבע לפי «כמי התוכנית הזו רצה». שירות Windows שרץ בלי פיקוח הוא חבילה אחת של מאגר המחשב והענקת הרשאות גישה למפתח הפרטי, ופקיעת תוקף של אישור וטביעת אצבע מקובעת הם הסיבות הקלאסיות לתקלת חיבור שמקורה באישור.

מפת הידע של המדריך המעשי למאגר האישורים ב-Windowsתרשים שמראה את הקשר בין מאגר האישורים (משתמש/מחשב), אישור לקוח, מפתח פרטי, שרשרת אישורים, CA שורש ו-CA ביניים, פקיעת תוקף וטביעת אצבע מול תקלת חיבור, הליך החלפה, פנקס, וסיכון של אישור בחתימה עצמיתמשתמש במחייבמחייבמחייבמחייבעלול לגרום לעלול לגרום לנבדק באמצעותמוגדר באמצעותמוגדר באמצעותנבדק באמצעותנבדק באמצעותנבדק באמצעותנבדק באמצעותנשמר בנבדק באמצעותנשמר במשתמש בנשמר במוגדר באמצעותמונעמונעעלול לגרום לשימוש לא מומלץ לשימוש לא מומלץ למענה מומלץ ליורש את תוכןנשמר בעלול לגרום למשתמש במחייבמשתמש בעלול לגרום לשימוש לא מומלץ למחייבצריך לקדום למשתמש במצמצםמחייבמענה מומלץ למענה מומלץ למאגר אישוריםאישור לקוחשירות Windowsמאגר האישורים של המחשבמפתח פרטיהרשאות גישה למפתח הפרטישרשרת אישוריםאישור CA בינייםאישור CA שורשפקיעת תוקף של אישורתקלת חיבור שמקורה באישורקיבוע טביעת אצבעמדיניות קבוצתית (Group Policy)Microsoft Intuneמאגר האישורים של המשתמשcertmgr.msccertlm.mscכונן Cert:קובץ PFXcertutilאישור לחתימת קודמאגר מפרסמים מהימניםיישום שולחני עם משתמש אינטראקטיביהחלפת אישורפנקס אישוריםאישור אד-הוק בחתימה עצמיתסיכון לניצול לרעה של נקודת האמוןבחירת אישור (חיפוש)מאגר «אישי» (My)בלבול בין מאגריםמאגר יישומים של IISהרצה ללא פיקוח ב-Task Schedulerייבוא כניתן-לייצואסיכון להוצאת מפתח פרטיהענקת שליטה מלאה ל-Everyoneרישום מראש של אישור אצל היעדמעבר לאישור חדשמחלקת X509Storeחיפוש אישור עם validOnlyמאפיין שימוש במפתח (Key Usage)הוצאת טביעת אצבע לתצורהרישום ללוג של האישור שנבחר

בתרשים, קו מלא מציין קשר שמתקיים תמיד וקו מקווקו מציין קשר מותנה (תנאי ההתקיימות מפורטים בהסבר של כל קשר בעמוד המפורט). רשימת כל הקשרים (סך הכול 41, עם אסמכתה ורמת ודאות) והגדרות המושגים המרכזיים מרוכזות בעמוד המפורט של מפת הידע (ביפנית). נתונים: JSON-LD / Turtle

2. תמונת מאגר האישורים — שני מקומות ומאגרים לוגיים

2.1. שני הקווים, משתמש ומחשב

מאגר האישורים ב-Windows נחלק בגדול לשני «מקומות».1

  • מאגר האישורים של המחשב (המחשב המקומי, LocalMachine): אחד למחשב, משותף לכל המשתמשים והשירותים במחשב. הישות נמצאת תחת HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates ברישום.2
  • מאגר האישורים של המשתמש (המשתמש הנוכחי, CurrentUser): שונה לכל חשבון משתמש. הישות נמצאת תחת HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates, כלומר חלק מפרופיל המשתמש.2

יש גם מאגר לפי חשבון שירות,3 והישות היא מפתח רישום לפי שם השירות.2 מה שצריך לתפוס קודם בשטח הם השניים הראשונים.

יש מפרט חשוב אחד. כל מאגר לוגי במאגר המשתמש, מלבד «אישי», מציג בירושה את תוכן המאגר באותו שם במאגר המחשב. 1 למשל אם שמים אישור CA פנימית ב«רשויות אישורי שורש מהימנות» במאגר המחשב, הוא יופיע גם ב«רשויות אישורי שורש מהימנות» של כל המשתמשים. ולהפך, רק מאגר «אישי» אינו מורש, ולכן לאישור לקוח (מה ששמים במאגר האישי) צריך להחליט בעצמכם «ממי הוא צריך להיראות». האסימטריה הזו היא גיבורת המאמר כולו.

מאגר המחשב ומאגר המשתמשמאגר המחשב הוא אחד למחשב ומשותף לכל המשתמשים והשירותים, ומאגר המשתמש שונה לכל חשבון ומציג בירושה את תוכן המחשב מלבד «אישי»משתמש (CurrentUser)שונה לכל חשבוןמחשב (LocalMachine)אחד למחשב, משותף לכל המשתמשים והשירותיםנראה בירושת תוכןירושהירושהאישי (My)※ אינו מורש = אתם מחליטים לאן לשיםרשויות אישורי שורש מהימנות (Root)רשויות אישור ביניים (CA)מפרסמים מהימנים (TrustedPublisher)אישי (My)רשויות אישורי שורש מהימנות (Root)רשויות אישור ביניים (CA)מפרסמים מהימנים (TrustedPublisher)

איור 1: מאגר המשתמש מציג בירושה את תוכן מאגר המחשב מלבד «אישי»; את מקום אישור הלקוח צריך להחליט בעצמכם.

2.2. המאגרים הלוגיים העיקריים

בתוך כל מקום יש מאגרים לוגיים לפי תפקיד. התיקיות שרואים ב-certmgr.msc / certlm.msc הן אלה, ומ-PowerShell ומשורת פקודה משתמשים בשם הפנימי באנגלית.24

שם תצוגה שם פנימי מה שמים שם
אישי My אישורים שהמחשב או המשתמש הזה משתמש בהם. אישורי לקוח ואישורי שרת כאן. גם הקישור למפתח הפרטי כאן
רשויות אישורי שורש מהימנות Root אישורי CA שורש שהם נקודת האמון. CA שמתחת למה ששמים כאן «מהימנה»
רשויות אישור ביניים CA אישורי CA ביניים שמחברים בין השורש לקצה. חומר לבניית שרשרת
מפרסמים מהימנים TrustedPublisher אישורים שסומכים עליהם כמפרסם של תוכנה חתומה (פרק 8)

2.3. שלושה חלונות הצצה — certmgr.msc / certlm.msc / כונן Cert:

יש שלושה אמצעים לראות את אותו מאגר.34

  • certmgr.msc: מסוף ניהול שפותח את מאגר המשתמש הנוכחי.
  • certlm.msc: מסוף ניהול שפותח את מאגר המחשב המקומי.
  • כונן Cert: ב-PowerShell: אפשר לתפעל את המאגר כמו מערכת קבצים בהיררכיה Cert:\CurrentUser\... ו-Cert:\LocalMachine\.... אישורים מזוהים בטביעת אצבע.

כשמוסיפים ידנית snap-in של אישורים ל-mmc.exe בוחרים יעד משלושה סוגים: «חשבון משתמש», «חשבון מחשב», «חשבון שירות». משתמש שאינו מנהל יכול לנהל רק את מאגר חשבון המשתמש שלו.3

הצעד הראשון בחקירת תקלה הוא ליישר «איזה מאגר האפליקציה רואה» עם «איזה מאגר אתם רואים». אם חוקרים תקלת שירות תוך מבט ב-certmgr.msc, המקום שונה ולעולם לא תגיעו לתשובה.

3. לאן לשים — טבלת החלטה לפי צורת ההרצה של התוכנית

קריטריון אחד. בחשבון של מי רצה התוכנית שמשתמשת באישור.

צורת הרצה חשבון הרצה המאגר לשים הערה
יישום שולחני שמשתמש אינטראקטיבי מפעיל המשתמש המחובר עצמו משתמש (Cert:\CurrentUser\My) נדרשת הטמעה לכל חשבון שמשתמש. במחשב משותף עם כמה אנשים שוקלים גם מאגר מחשב
שירות Windows LocalSystem / NETWORK SERVICE / חשבון שירות ייעודי מחשב (Cert:\LocalMachine\My) מלבד LocalSystem (NETWORK SERVICE, חשבון ייעודי וכו’) חובה להעניק הרשאת קריאה למפתח הפרטי (פרק 4). LocalSystem קורא בהרשאת SYSTEM כברירת מחדל
יישום ווב על IIS זהות מאגר היישומים מחשב כמו למעלה
הרצה בלי פיקוח ב-Task Scheduler (הרצה בין שהמשתמש מחובר ובין שלא) החשבון שצוין במשימה מומלץ מחשב אפשר גם במאגר המשתמש של חשבון ההרצה, אבל זה רק מוסיף בדיקות של פרופיל ושל נראות המאגר, בלי יתרון ממשי
הגשה אלקטרונית ואימות ווב בדפדפן המשתמש המחובר עצמו משתמש טבעי גם במובן של «לא לתת לאחרים מלבד מי שחילקתם לו»

כשמסופקים, מה שרץ בלי פיקוח — מאגר המחשב; מה שאדם מפעיל — מאגר המשתמש.

3.1. ניתוח התאונה הקלאסית — «בפיתוח עבד, ובהפיכה לשירות לא נמצא»

אפשר לשחזר את התאונה הזו במדויק בשלבים האלה.

  1. המפתח מייבא pfx בלחיצה כפולה במחשב שלו. ברירת המחדל של האשף היא «המשתמש הנוכחי», ולכן האישור נכנס למאגר המשתמש של חשבון המפתח.
  2. היישום בפיתוח רץ מ-Visual Studio, כלומר בחשבון המפתח, ולכן פתיחת StoreLocation.CurrentUser מוצאת את האישור. עובד.
  3. בשרת הייצור רושמים כשירות Windows. השירות רץ כ-NETWORK SERVICE או כחשבון ייעודי.
  4. ה-CurrentUser שהקוד של השירות פותח הוא מאגר המשתמש של חשבון הרצת השירות. שם ריק. «האישור לא נמצא».
בפיתוח עבד, וכשירות לא נמצאאישור שהוכנס למאגר המשתמש של המפתח אינו נראה מ-CurrentUser של שירות שרץ בחשבון אחרשרת ייצורמכונת פיתוחמציבים את אותה תוכניתה-CurrentUser שהקוד פותח הואמאגר המשתמש של חשבון השירותרישום כשירות Windowsחשבון ההרצה הוא NETWORK SERVICE וכו'שם ריק→ «האישור לא נמצא»נכנס למאגר המשתמששל חשבון המפתחייבוא בלחיצה כפולה על pfxברירת המחדל באשף היא «המשתמש הנוכחי»הרצה מ-Visual Studio= רץ בחשבון המפתחפתיחת CurrentUser מוצאת→ עובד

איור 2: מאגר המשתמש של המפתח ומאגר המשתמש של חשבון השירות שונים; הרצה בפיתוח אינה מבטיחה שהאישור יימצא בייצור.

הנקודה היא שלמאגר המשתמש יש «כמספר החשבונות». גם אם מנהל פותח certmgr.msc ואומר «הנה, זה בפנים», זה המאגר של המנהל עצמו, לא של חשבון השירות. הטיפול אינו העתקה מזדמנת אלא לשים מחדש במאגר המחשב, וליישר גם את הקוד ל-StoreLocation.LocalMachine. והענקת ההרשאות בפרק הבא באה כחבילה אחת.

4. מפתח פרטי והרשאות גישה — התאונה הקלאסית השנייה

4.1. אישור ומפתח פרטי הם דבר שונה

מה שנראה ברשימת מאגר האישורים הוא האישור (מידע ציבורי), לא המפתח הפרטי עצמו. מה שנחוץ בפועל באימות לקוח הוא עיבוד חתימה במפתח הפרטי, ולכן «נראה ברשימה» ו«אפשר להשתמש» הם בעיה נפרדת. אם מבלבלים ביניהם מתקבלת תקלה קשה לראות: «האישור קיים אבל לחיצת היד של TLS נכשלת», «שגיאה פנימית בסגנון Access Denied».

4.2. ייבוא pfx בפועל — ייצוא כן או לא הוא החלטה

זוג האישור והמפתח הפרטי מועבר בקובץ pfx ‏(PKCS #12), ומייבאים למאגר ב-Import-PfxCertificate.6

$pwd = Get-Credential -UserName '(הזינו סיסמה למטה)' -Message 'סיסמת ה-PFX'
Import-PfxCertificate -FilePath C:\certs\client.pfx `
    -CertStoreLocation Cert:\LocalMachine\My -Password $pwd.Password

החשוב כאן הוא התנהגות ברירת המחדל: כל עוד לא מצרפים -Exportable, אי אפשר לייצא מחדש את המפתח הפרטי שיובא. 6 לשים הכול כניתן-לייצוא «כדי שנוכל להעביר אחר כך» זה להוסיף נתיב אחד להוצאת מפתח פרטי. מפעילים שמירה בטוחה של קובץ ה-pfx המקורי, ובמאגר המפתח הפרטי אינו ניתן לייצוא כבסיס — זו ההמלצה שלנו. ושמירת קובץ ה-pfx המקורי והסיסמה שלו היא בדיוק מה שנוטה להישאר בטקסט גלוי. את החשיבה מסדרים ב«שמירת סודות ביישומי Windows — להימנע מתצורה גלויה עם DPAPI» וב«טיפול בטוח באישורים ב-PowerShell».

4.3. הענקת הרשאות מפתח פרטי לחשבון שירות

למפתח הפרטי של אישור במאגר המחשב, בדרך כלל כברירת מחדל אי אפשר לקרוא מלבד מנהלים ו-SYSTEM. לכן שירות שרץ כ-LocalSystem קורא את המפתח הפרטי כברירת מחדל, אבל כשמריצים בחשבון אחר — NETWORK SERVICE, חשבון שירות ייעודי, זהות מאגר יישומים של IIS — מעניקים במפורש הרשאת קריאה לחשבון ההרצה. את ההליך אפשר לעשות מממשק ה-snap-in של האישורים.5

  1. פותחים certlm.msc (או snap-in אישורים ליעד חשבון מחשב).
  2. ב«אישי» → «אישורים» לוחצים ימני על האישור היעד, ומתוך «כל המשימות» פותחים «ניהול מפתחות פרטיים».
  3. בלשונית «אבטחה» מוסיפים את חשבון ההרצה (NETWORK SERVICE, חשבון שירות ייעודי, זהות מאגר יישומים של IIS וכו’) ומתירים «קריאה».5

אין צורך בשליטה מלאה. לחתימה מספיקה קריאה. ולהפך, לתת Everyone שליטה מלאה כי «זה לא עובד» זה להוריד את המפתח הפרטי לטיפול כמו סיסמה גלויה — אסור בהחלט. הצבה במאגר המחשב והענקת הרשאות למפתח הפרטי תמיד חבילה אחת — לכתוב את זה בספר ההליך מספיק כדי שהתאונות מהסוג הזה ייעלמו.

5. למנוע תאונת פקיעת תוקף — ספירה, החלפה, פנקס

5.1. ספירה ב-PowerShell

תוקף האישור נמצא במאפיין NotAfter. אפשר לספור באופן מכני עם Get-ChildItem על כונן Cert:.4

# רשימת «אישי» במאגר המחשב לפי תוקף
Get-ChildItem Cert:\LocalMachine\My |
    Sort-Object NotAfter |
    Format-Table Thumbprint, Subject, NotAfter

# שליפה רק של מה שיפקע בתוך 60 ימים (0 מחזיר שכבר פג)
Get-ChildItem -Path Cert:\LocalMachine\My -ExpiringInDays 60

-ExpiringInDays הוא פרמטר שמחזיר «אישורים שיפקעו בתוך מספר הימים שצוין», ו-0 מחזיר אישורים שכבר פג תוקפם.4 הופכים את זה למשימה מתוזמנת חודשית על כל השרתים, ומרכזים תוצאות לדואר או לפנקס — וזה לבדו כמעט מונע תאונות בסגנון «בבוקר יום שני אימות הזכאות לא עובר כי פג התוקף».

5.2. הליך ההחלפה — תקופת מקביליות ומלכודת טביעת האצבע

עדכון אישור אינו «מוחקים ושמים» אלא «מוסיפים, מחליפים, מאשרים, ואז מוחקים».

  1. מייבאים את האישור החדש (pfx) לאותו מאגר. טביעת האצבע שונה, ולכן ישן וחדש יכולים לדור יחד באותו מאגר.
  2. מעניקים הרשאות למפתח הפרטי של האישור החדש (פרק 4). כאן קל לשכוח בעדכון. ההרשאה צמודה לכל מפתח פרטי של אישור, ולכן אחרי החלפת אישור מעניקים מחדש.
  3. דיווח למערכת היעד (כש-API דורש רישום מראש של האישור) משלימים קודם, תוך המשך תפעול באישור הישן, ומבטיחים תקופת מקביליות שבה גם ישן וגם חדש מתקבלים. אם מחליפים קודם, הצד השני דוחה את האישור החדש והתקשורת בייצור נעצרת.
  4. מחליפים את תצורת היישום לאישור החדש, ומאשרים פעולה.
  5. אחרי תקופה מספקת, מוחקים את האישור הישן.
עדכון אישור מוסיפים ואז מחליפיםמייבאים pfx חדש לאותו מאגר, מעניקים הרשאות, רושמים מראש אצל היעד, מחליפים טביעת אצבע, ואחרי תקופת המקביליות מוחקים את הישן1. ייבוא pfx חדש לאותו מאגר(ישן וחדש יחד)2. הענקת הרשאותלמפתח הפרטי של האישור החדש3. רישום מראש אצל היעד(המשך תפעול באישור הישן)4. החלפת טביעת האצבע בתצורההחלפה ואישור פעולה5. אחרי תקופת המקביליותמחיקת האישור הישן

איור 3: סדר החלפת אישור הוא הוספה → הרשאות → רישום מראש → החלפת תצורה → מחיקת הישן; לא לשכוח עדכון טביעת אצבע.

המלכודת הגדולה כאן היא טביעת אצבע שכתובה בקובץ תצורה או בקוד. טביעת אצבע ייחודית לכל אישור, ולכן בעדכון היא תמיד משתנה. אם ולו מקום אחד עדיין מפנה לטביעת האצבע הישנה, מתקבל «עדכנו את האישור ועדיין אי אפשר להתחבר». הדרך הבטוחה היא לנהל בפנקס איפה כתובה טביעת האצבע (תצורת יישום, קישור IIS, סקריפט, דיווח ליעד).

5.3. ההמלצה לפנקס אישורים

פנקס — די בגליון Excel אחד בהתחלה. לכל הפחות עמודות שימוש / מנפיק / נושא / טביעת אצבע / מקום (שם שרת + מאגר) / חשבון עם הרשאת מפתח פרטי / תוקף / קישור להליך עדכון / אחראי, ומצליבים מול תוצאת הספירה ב-5.1. מהות תאונת האישורים אינה בעיית טכנולוגיה אלא בעיית «לאף אחד אין רשימה», ולכן הפנקס הוא מה שהכי עובד.

6. קריאת אימות וכישלון — שרשרת והפצת שורש

6.1. יסודות אימות השרשרת ו-certutil

שגיאות בסגנון «האישור הזה אינו מהימן» הן מצב שבו השרשרת (נתיב ההוכחה) מהאישור הקצה עד CA השורש קרועה איפשהו. לחיתוך נוח certutil.7

שלוש הסיבות הקלאסיות לחיתוך אימות שרשרתאי אפשר להשיג CA ביניים, השורש לא הופץ, או שפג תוקף האישור הקצה, וכל אחד מהם גורם לשגיאת אמוןאי אפשר להשיג(לא בהצגה, לא ב-AIA, לא במאגר)לא הופץפג תוקףהאישור הקצה(אישור לקוח / אישור שרת)אישור CA בינייםמקום: מאגר רשויות אישור ביניים (CA)אישור CA שורשמקום: רשויות אישורי שורש מהימנות (Root)אי אפשר לבנות שרשרת(סיבה קלאסית 1)שגיאת «אינו מהימן»(סיבה קלאסית 2)שגיאת תקופת תוקף(סיבה קלאסית 3)

איור 4: השרשרת נחתכת כשחסר CA ביניים או שורש, או בגלל תקופת תוקף; קובעים את השכבה ב-certutil.

:: בניית שרשרת ואימות לקובץ אישור (כולל הבאת URL לבדיקת ביטול)
certutil -urlfetch -verify client.cer

:: אם היישום היעד משתמש במאגר המשתמש, מאמתים באותו הקשר עם -user
certutil -user -urlfetch -verify client.cer

:: dump לתוכן המאגר (-user פונה למאגר המשתמש)
certutil -store My
certutil -user -store My

certutil -verify מאמת אישור, CRL ושרשרת, ואם לא מציינים CACertFile הוא בונה שרשרת מלאה ומאמת.7 הפלט ארוך, אבל אפשר לקרוא באיזו שכבה נקטע האמון והאם מידע הביטול הגיע. הסיבות הטיפוסיות הן (1) אי אפשר להשיג אישור CA ביניים (העמית ב-TLS לא שלח, גם ממידע AIA באישור אי אפשר לקבל, וגם לא נמצא במאגר «רשויות אישור ביניים»), (2) שורש ה-CA הפנימית לא הופץ ל«רשויות אישורי שורש מהימנות», (3) פג תוקף האישור עצמו. CA ביניים נפתר גם בהצגה מהעמית או בהבאה אוטומטית דרך AIA, ולכן הצבה במאגר כדאי לראות כ«אחד האמצעים להבטיח».

6.2. הפצת שורש של CA פנימית וחתימה עצמית — ב-GPO/Intune

כשמשתמשים ב-CA פנימית או באישור בחתימה עצמית לבדיקה, צריך להפיץ את אישור השורש לכל מחשב. לא שמים ידנית מחשב-מחשב, אלא מעמיסים על מנגנון הפצה.

  • סביבת Active Directory ‏(GPO): מייבאים אישור ל«רשויות אישורי שורש מהימנות» תחת תצורת מחשב\מדיניות\הגדרות Windows\הגדרות אבטחה\מדיניות מפתח ציבורי ב-Group Policy, והוא מופץ למחשבי היעד.8
  • סביבה בניהול Intune: מפיצים אישורי CA שורש/ביניים בפרופיל «אישור מהימן». ב-Windows אפשר לבחור את מאגר היעד (שורש/ביניים של המחשב, ביניים של המשתמש).9

כפי שנאמר ב-2.1, אם שמים בשורש מאגר המחשב, כל המשתמשים סומכים.1 ולכן צריך להביט גם בסיכון ההפוך. תפעול שמכניס אישור בחתימה עצמית ל«רשויות אישורי שורש מהימנות» הוא נטיעת נקודת אמון חדשה במחשב. אם המפתח הפרטי דולף, זה בסיס להנפקת אישורים שמתחזים לכל אתר או תוכנה. לתפעול קבוע הנתיב הוא להקים CA פנימית עם הגנה נאותה על המפתח, או להתקרב לאישור של CA ציבורית; שורש בחתימה עצמית ככלל הוא «סביבת בדיקה בלבד, עם תוקף חתוך».

7. מבט המפתח — שימוש נכון במאגר מ-.NET

7.1. חיפוש לפי טביעת אצבע ב-X509Store

מ-.NET פותחים מאגר ב-X509Store ומשיגים אישור ב-Find.1011

using System.Security.Cryptography.X509Certificates;

static X509Certificate2 GetClientCertificate(string thumbprint)
{
    using var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

    var found = store.Certificates.Find(
        X509FindType.FindByThumbprint, thumbprint, validOnly: true);

    if (found.Count == 0)
        throw new InvalidOperationException(
            $"האישור לא נמצא: טביעת אצבע={thumbprint}, " +
            $"מקום={store.Location}\\{store.Name}");

    var cert = found[0];
    if (!cert.HasPrivateKey)
        throw new InvalidOperationException(
            $"האישור קיים אבל אין מפתח פרטי מקושר (ייבוא מ-.cer " +
            $"וכו'): טביעת אצבע={thumbprint}, מקום={store.Location}\\{store.Name}");

    return cert;
}

ההחלטה מפרק 3 מתחברת לכאן ישירות. בקוד שרץ כשירות — StoreLocation.LocalMachine; ביישום אינטראקטיבי — StoreLocation.CurrentUser. עוד נקודה: שימו לב לארגומנט השלישי validOnly של Find. true מחזיר רק אישורים תקפים שעברו אימות. 11 זה ביטוח לא לתפוס אישור שפג תוקפו, אבל גם אישור בחתימה עצמית לבדיקה שהשרשרת שלו אינה מהימנה נופל לצד «לא נמצא», ולכן כש«הוא בפנים אבל לא נמצא» חושדים גם כאן. ובהודעת השגיאה כשלא נמצא תמיד שמים, כמו בדוגמה למעלה, איזה מאגר חיפשתם. זמן החקירה של תאונת פרק 3 משתנה בסדרי גודל.

7.2. לשים אישור לקוח על HttpClient

את האישור שהושג מוסיפים ל-HttpClientHandler.ClientCertificates ומציגים לשרת. האוסף הזה הוא קבוצת האישורים שמוצגת לשרת באימות לקוח מבוסס-אישור.12

var handler = new HttpClientHandler();
handler.ClientCertificates.Add(GetClientCertificate(thumbprint));

var client = new HttpClient(handler);
// מכאן משתמשים כ-HttpClient רגיל

ב-.NET Core מצוין בתיעוד שאם לאישור יש מאפיין שימוש במפתח (Key Usage), הוא לא ישמש לשליחת בקשה אלא אם הוא כולל «Digital Signature».12 כשאתם בצד שמבקש הנפקת אישור לקוח, העבירו נכון את השימוש (אימות לקוח). ו-HttpClient עם דפוס יצירה שגוי גורם לדלדול שקעים ולבעיות מעקב DNS. תכנון שמאריך את חיי ה-handler כולו מטופל ב«אסור לעטוף HttpClient ב-using».

7.3. בעיית טביעת אצבע מקובעת שמתה בהחלפה

חיפוש לפי טביעת אצבע בטוח, אבל אם משובצת טביעת אצבע בקוד כל עדכון אישור דורש בנייה ושחרור. הטיפול בתכנון הוא בשלושה שלבים.

  • מינימום: מוציאים את טביעת האצבע לקובץ תצורה (appsettings וכו’) כדי שאפשר יהיה להחליף בלי שחרור. את מקום התצורה שמים בפנקס של 5.3.
  • צעד נוסף: מחפשים לפי שם נושא או מנפיק, ומשלבים עם validOnly: true כדי לבחור «מבין התקפים כעת בשם הזה, זה עם NotAfter הרחוק ביותר». בתקופת מקביליות הוא עובר אוטומטית לאישור החדש. אבל יש סיכון לתפוס אישור לא מכוון באותו שם, ולכן מאשרים מנפיק ומוציאים ללוג כחבילה. והמעבר האוטומטי הזה מתקיים רק כשהיעד אינו דורש רישום מראש של האישור. ב-API שדורש רישום מראש (5.2) הוא עלול לעבור לבד לאישור שיובא בלבד ועדיין לא נרשם, ולעצור תקשורת — לכן נשארים בשיטת ההוצאה לתצורה, ומחליפים אחרי שאישרתם שהרישום הושלם.
  • סוגרים בתפעול: בכל שיטה, בהפעלה משאירים בלוג «איזה אישור (טביעת אצבע, תוקף) נבחר». השורה הזו עובדת גם בחקירת תקלה וגם בהצלבה מול הפנקס.

8. הקשר לאישור חתימת קוד — מאגר «מפרסמים מהימנים»

עד כאן טופלו אישורים לתקשורת (TLS), אבל במאגר האישורים מתגורר עוד עולם — חתימת קוד. נקודת המגע היא מאגר «מפרסמים מהימנים (TrustedPublisher)» בטבלה ב-2.2, המקום שבו רושמים כמהימן את אישור המפרסם של תוכנה חתומה. הוא קיים גם במקום המשתמש וגם במקום המחשב,10 ומשמש בתפעול כמו להפיץ ב-GPO את מפרסם היישום הפנימי ל-TrustedPublisher בכל מחשב.

אם אתם בצד «שמפיץ» יישום וצריכים לטפל בחתימת קוד ובאזהרת SmartScreen («Windows הגנה על המחשב»), זה מרוכז במאמר נפרד «למה מופיע «Windows הגנה על המחשב»». הידע במאמר הזה (שני קווי המאגר, הפצת שורש) משמש כמו שהוא כידע רקע.

9. סיכום

  • למאגר האישורים שני קווים: משתמש (CurrentUser) ומחשב (LocalMachine). certmgr.msc / certlm.msc / כונן Cert: הם שלושה חלונות לאותו דבר. הצעד הראשון בחקירה הוא ליישר «על איזה מאגר מדברים».
  • את מקום ההשמה קובעים לפי «כמי התוכנית רצה». הרצה בלי פיקוח (שירות, IIS, משימה) — מאגר המחשב; יישום אינטראקטיבי — מאגר המשתמש, ככלל.
  • «בפיתוח עבד, ובייצור לא נמצא» נגרם מכך שמאגר המשתמש של המפתח ומאגר המשתמש של חשבון השירות הם דבר שונה. מיישרים למאגר המחשב + StoreLocation.LocalMachine.
  • הצבה במאגר המחשב והענקת הרשאת קריאה ב«ניהול מפתחות פרטיים» הן חבילה אחת. לא לשכוח להעניק מחדש בעדכון.
  • ייבוא pfx כברירת מחדל אינו ניתן לייצוא. -Exportable רק כשבאמת נחוץ. כוללים בתכנון גם שמירת קובץ ה-pfx המקורי והסיסמה.
  • פקיעת תוקף מונעים בספירה מחזורית עם Get-ChildItem Cert: ... -ExpiringInDays ובפנקס אישורים. החלפה בסדר «הוספה → החלפה → אישור → מחיקה», עם זהירות לדליפת עדכון טביעת האצבע בתצורה.
  • חיתוך שרשרת ב-certutil -urlfetch -verify. שורש של CA פנימית מפיצים ב-GPO/Intune, ותפעול שמכניס חתימה עצמית לשורש — סביבת בדיקה בלבד, עם תוקף.
  • בקוד מוציאים טביעת אצבע לתצורה ומשאירים בלוג את האישור שנבחר. זה לבדו משנה את הטיפול בתקלות שמקורן באישור.

מאמרים קשורים

תחומי ייעוץ קשורים

KomuraSoft LLC מטפלת בפיתוח יישומים עסקיים שמשלבים Web API עם אישור לקוח (API בנקאי, אימות זכאות מקוון וכו’), בחקירת תקלות בסגנון «האישור לא נמצא» ו«אחרי עדכון אי אפשר להתחבר», ובארגון הליך החלפת אישורים. אפשר להתייעץ כבר מהשלב שבו לא ברור איזה מאגר להסתכל עליו.

מקורות

  1. Microsoft Learn, Local Machine and Current User Certificate Stores. על כך שמאגר האישורים של המחשב מקומי למחשב ומשותף לכל המשתמשים ונמצא תחת HKEY_LOCAL_MACHINE; על כך שמאגר האישורים של המשתמש הוא לפי חשבון משתמש ונמצא תחת HKEY_CURRENT_USER; ועל כך שמאגר המשתמש יורש את תוכן מאגר המחשב מלבד מאגר «אישי» (אישור שנוסף ל«רשויות אישורי שורש מהימנות» של המחשב מופיע גם באותו מאגר אצל כל משתמש).  2 3 4

  2. Microsoft Learn, System Store Locations. על מיקום הרישום של CERT_SYSTEM_STORE_CURRENT_USER / CERT_SYSTEM_STORE_LOCAL_MACHINE (Software\Microsoft\SystemCertificates תחת HKEY_CURRENT_USER / HKEY_LOCAL_MACHINE בהתאמה); על כך שהמאגרים הלוגיים המוגדרים הם MY, Root, Trust, CA; על כך שמאגר לשירות נמצא במפתח רישום לפי שם השירות (Software\Microsoft\Cryptography\Services\ServiceName\SystemCertificates); ועל כך שקיים בנפרד מאגר להפצה ב-Group Policy.  2 3 4 5

  3. Microsoft Learn, How to: View certificates with the MMC snap-in. על כך ש-certlm.msc מנהל אישורים של המכשיר המקומי (המחשב המקומי) ו-certmgr.msc מנהל אישורים של המשתמש הנוכחי; על כך של-snap-in האישורים יש שלושה יעדים: «חשבון מחשב», «חשבון משתמש», «חשבון שירות»; ועל כך שמשתמש שאינו מנהל יכול לנהל רק אישורים של חשבון המשתמש שלו.  2 3 4

  4. Microsoft Learn, about_Certificate_Provider. על כך שכונן Cert: ב-PowerShell הוא מרחב שמות היררכי עם שני מקומות מאגר, CurrentUser ו-LocalMachine; על כך שאפשר למנות מאגרים ואישורים ב-Get-ChildItem; על כך שהפרמטר -ExpiringInDays מחזיר אישורים שיפקעו בתוך מספר הימים שצוין (0 לשכבר פג); על פרמטרים דינמיים כמו -CodeSigningCert; על כך שתוקף נשמר במאפיין NotAfter; ועל כך שאישורים מזוהים בטביעת אצבע.  2 3 4 5 6

  5. Microsoft Learn, How to Modify Private Key Permissions to Support Management Server or Streaming Server. על ההליך שבו ב-snap-in אישורים ליעד מאגר המחשב המקומי פותחים «ניהול מפתחות פרטיים» (Manage Private Keys), ובלשונית «אבטחה» מוסיפים הרשאת «קריאה» לחשבון הרצת השירות (למשל Network Service).  2 3

  6. Microsoft Learn, Import-PfxCertificate. על כך ש-Import-PfxCertificate מייבא אישור ומפתח פרטי מקובץ PFX למאגר שצוין; על כך שאם לא מציינים את המתג -Exportable אי אפשר לייצא את המפתח הפרטי שיובא; ועל התחביר ודוגמאות השימוש בפרמטרים -CertStoreLocation, -Password, -FilePath.  2 3

  7. Microsoft Learn, certutil. על כך ש-certutil -verify מאמת אישור, CRL ושרשרת אישורים, ושבלי ציון קובץ אישור CA הוא בונה שרשרת מלאה ומאמת; על זמינות האפשרות -urlfetch; ועל כך ש-certutil -store עושה dump למאגר אישורים, ושעם האפשרות -user ניגשים למאגר המשתמש במקום למאגר המחשב.  2

  8. Microsoft Learn, Distribute Certificates to Client Computers by Using Group Policy. על ההליך לייבא אישור ל«רשויות אישורי שורש מהימנות» תחת «תצורת מחשב\מדיניות\הגדרות Windows\הגדרות אבטחה\מדיניות מפתח ציבורי» ב-Group Policy ולהפיץ למחשבי לקוח בדומיין, ועל ההרשאות הנדרשות (ברמה של Domain Admins / Enterprise Admins). 

  9. Microsoft Learn, Create trusted certificate profiles in Microsoft Intune. על כך שפרופיל «אישור מהימן» ב-Intune הוא מנגנון להפצת אישור CA שורש או ביניים למכשירים מנוהלים; על כך שהוא משמש כהנחה לפרופילי אישור SCEP/PKCS כדי לבסס אמון ב-CA השורש; ועל כך שב-Windows אפשר לבחור כמאגר יעד «מאגר אישורי מחשב — שורש», «מאגר אישורי מחשב — ביניים», «מאגר אישורי משתמש — ביניים». 

  10. Microsoft Learn, X509Store Class. על כך שאפשר לבנות X509Store עם StoreName ו-StoreLocation (CurrentUser / LocalMachine), לפתוח מאגר בשיטת Open וב-OpenFlags (ReadOnly, OpenExistingOnly וכו’), ולהשיג אוסף אישורים במאפיין Certificates; על כך ששמות המאגר הסטנדרטיים כוללים My, Root, CA, TrustedPublisher וכו’; ועל כך שמאגר TrustedPublisher קיים גם ב-CurrentUser וגם ב-LocalMachine.  2

  11. Microsoft Learn, X509Certificate2Collection.Find(X509FindType, Object, Boolean) Method. על כך ששיטת Find מחפשת אישורים לפי X509FindType (FindByThumbprint וכו’) וערך חיפוש; ועל כך שכשמציינים true בארגומנט השלישי validOnly מוחזרים רק אישורים תקפים שעברו אימות.  2

  12. Microsoft Learn, HttpClientHandler.ClientCertificates Property. על כך שמאפיין ClientCertificates הוא X509CertificateCollection שמוצג לשרת באימות לקוח מבוסס-אישור; ועל כך שב-.NET Core, אם לאישור יש מאפיין שימוש במפתח, נדרש שיכלול «Digital Signature».  2

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

מה ההבדל בין certmgr.msc ל-certlm.msc?
המאגר שהם פותחים שונה. certmgr.msc פותח את מאגר האישורים של המשתמש המחובר (המשתמש הנוכחי, CurrentUser), ו-certlm.msc פותח את מאגר האישורים של המחשב (המחשב המקומי, LocalMachine). מאגר המחשב משותף לכל המשתמשים והשירותים במחשב, ולניהול נדרשות הרשאות מנהל. משתמש שאינו מנהל יכול לנהל רק את מאגר המשתמש שלו. בשניהם התוכן מחולק למאגרים לוגיים כמו «אישי» ו«רשויות אישורי שורש מהימנות», ומ-PowerShell רואים את אותו מבנה כ-Cert:\CurrentUser ו-Cert:\LocalMachine.
אישור לקוח — לשים במאגר המשתמש או במאגר המחשב?
מחליטים לפי «כמי» רצה התוכנית שמשתמשת באישור. ביישום שולחני שמשתמש אינטראקטיבי מפעיל, הבסיס הוא מאגר המשתמש של אותו אדם (Cert:\CurrentUser\My). בתוכנית שרצה בלי פיקוח כשירות Windows, מאגר יישומים של IIS או Task Scheduler, שמים במאגר המחשב (Cert:\LocalMachine\My) ומעניקים לחשבון ההרצה הרשאת קריאה למפתח הפרטי. מאגר המשתמש שונה לכל חשבון, ולכן אישור שמפתח שם במאגר המשתמש שלו אינו נראה לשירות שרץ בחשבון אחר. זו הסיבה הקלאסית ל«בפיתוח עבד, ובייצור לא נמצא».
כששירות Windows לא מוצא את האישור או לא יכול להשתמש בו, מה בודקים?
שני שלבים. ראשית «איזה מאגר הוא רואה». אם הקוד פותח StoreLocation.CurrentUser, זה מאגר המשתמש של חשבון הרצת השירות, וזה דבר אחר מהמאגר שהמנהל רואה ב-certmgr.msc. מעבירים את האישור למאגר המחשב, ומתאימים גם את הקוד ל-StoreLocation.LocalMachine. שנית «האם אפשר לקרוא את המפתח הפרטי». לראות את האישור ברשימה ולהשתמש במפתח הפרטי הם דבר שונה, ולמפתח הפרטי במאגר המחשב בדרך כלל יש גישה כברירת מחדל רק למנהלים ול-SYSTEM. ב-certlm.msc פותחים «ניהול מפתחות פרטיים» מהאישור היעד, ומעניקים «קריאה» לחשבון הרצת השירות (NETWORK SERVICE וכו').
איך מוצאים מראש פקיעת תוקף של אישור ב-PowerShell?
אפשר לספור עם Get-ChildItem על כונן Cert:. למשל Get-ChildItem Cert:\LocalMachine\My | Sort-Object NotAfter | Format-Table Thumbprint, Subject, NotAfter מציג את המאגר האישי של מאגר המחשב לפי תוקף. עם הפרמטר -ExpiringInDays אפשר לשלוף רק «אישורים שיפקעו בתוך מספר הימים שצוין», ו-0 מחזיר אישורים שכבר פג תוקפם. מריצים את זה מדי חודש על כל השרתים ומצליבים מול פנקס האישורים — ורוב תאונות «בבוקר אי אפשר להתחבר כי פג התוקף» נמנעות.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג