מדריך מעשי למאגר האישורים ב-Windows — משתמש או מחשב, לאן שמים
· Go Komura · אישורים, 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 שרץ בלי פיקוח הוא חבילה אחת של מאגר המחשב והענקת הרשאות גישה למפתח הפרטי, ופקיעת תוקף של אישור וטביעת אצבע מקובעת הם הסיבות הקלאסיות לתקלת חיבור שמקורה באישור.
flowchart LR
accTitle: מפת הידע של המדריך המעשי למאגר האישורים ב-Windows
accDescr: תרשים שמראה את הקשר בין מאגר האישורים (משתמש/מחשב), אישור לקוח, מפתח פרטי, שרשרת אישורים, CA שורש ו-CA ביניים, פקיעת תוקף וטביעת אצבע מול תקלת חיבור, הליך החלפה, פנקס, וסיכון של אישור בחתימה עצמית
certificate_store["מאגר אישורים"]
client_certificate["אישור לקוח"]
windows_service["שירות Windows"]
localmachine_store["מאגר האישורים של המחשב"]
private_key["מפתח פרטי"]
private_key_acl["הרשאות גישה למפתח הפרטי"]
certificate_chain["שרשרת אישורים"]
intermediate_ca["אישור CA ביניים"]
root_ca["אישור CA שורש"]
certificate_expiry["פקיעת תוקף של אישור"]
certificate_failure["תקלת חיבור שמקורה באישור"]
thumbprint_hardcode["קיבוע טביעת אצבע"]
group_policy["מדיניות קבוצתית (Group Policy)"]
intune["Microsoft Intune"]
currentuser_store["מאגר האישורים של המשתמש"]
certmgr_msc["certmgr.msc"]
certlm_msc["certlm.msc"]
cert_drive["כונן Cert:"]
pfx["קובץ PFX"]
certutil["certutil"]
code_signing_cert["אישור לחתימת קוד"]
trusted_publisher_store["מאגר מפרסמים מהימנים"]
desktop_app["יישום שולחני עם משתמש אינטראקטיבי"]
cert_renewal["החלפת אישור"]
cert_ledger["פנקס אישורים"]
self_signed_cert["אישור אד-הוק בחתימה עצמית"]
trust_anchor_risk["סיכון לניצול לרעה של נקודת האמון"]
cert_selection["בחירת אישור (חיפוש)"]
personal_store["מאגר «אישי» (My)"]
store_mismatch["בלבול בין מאגרים"]
iis_apppool["מאגר יישומים של IIS"]
task_scheduler["הרצה ללא פיקוח ב-Task Scheduler"]
exportable_import["ייבוא כניתן-לייצוא"]
key_exfiltration_risk["סיכון להוצאת מפתח פרטי"]
everyone_full_control["הענקת שליטה מלאה ל-Everyone"]
partner_registration["רישום מראש של אישור אצל היעד"]
cert_switchover["מעבר לאישור חדש"]
x509store["מחלקת X509Store"]
validonly_search["חיפוש אישור עם validOnly"]
key_usage["מאפיין שימוש במפתח (Key Usage)"]
config_externalization["הוצאת טביעת אצבע לתצורה"]
cert_choice_logging["רישום ללוג של האישור שנבחר"]
windows_service -.->|"משתמש ב"| localmachine_store
client_certificate -->|"מחייב"| private_key
windows_service -.->|"מחייב"| private_key_acl
certificate_chain -.->|"מחייב"| intermediate_ca
certificate_chain -->|"מחייב"| root_ca
certificate_expiry -.->|"עלול לגרום ל"| certificate_failure
thumbprint_hardcode -.->|"עלול לגרום ל"| certificate_failure
certificate_failure -.->|"נבדק באמצעות"| certificate_chain
root_ca -.->|"מוגדר באמצעות"| group_policy
root_ca -.->|"מוגדר באמצעות"| intune
currentuser_store -->|"נבדק באמצעות"| certmgr_msc
localmachine_store -->|"נבדק באמצעות"| certlm_msc
certificate_store -->|"נבדק באמצעות"| cert_drive
certificate_expiry -->|"נבדק באמצעות"| cert_drive
private_key -.->|"נשמר ב"| pfx
certificate_chain -->|"נבדק באמצעות"| certutil
code_signing_cert -.->|"נשמר ב"| trusted_publisher_store
desktop_app -.->|"משתמש ב"| currentuser_store
root_ca -.->|"נשמר ב"| localmachine_store
private_key_acl -.->|"מוגדר באמצעות"| certlm_msc
cert_renewal -.->|"מונע"| certificate_failure
cert_ledger -.->|"מונע"| certificate_expiry
self_signed_cert -.->|"עלול לגרום ל"| trust_anchor_risk
thumbprint_hardcode -->|"שימוש לא מומלץ ל"| cert_selection
self_signed_cert -->|"שימוש לא מומלץ ל"| root_ca
cert_ledger -->|"מענה מומלץ ל"| certificate_expiry
currentuser_store -->|"יורש את תוכן"| localmachine_store
client_certificate -->|"נשמר ב"| personal_store
store_mismatch -->|"עלול לגרום ל"| certificate_failure
iis_apppool -.->|"משתמש ב"| localmachine_store
iis_apppool -->|"מחייב"| private_key_acl
task_scheduler -.->|"משתמש ב"| localmachine_store
exportable_import -->|"עלול לגרום ל"| key_exfiltration_risk
everyone_full_control -->|"שימוש לא מומלץ ל"| private_key_acl
cert_renewal -.->|"מחייב"| private_key_acl
partner_registration -.->|"צריך לקדום ל"| cert_switchover
x509store -->|"משתמש ב"| certificate_store
validonly_search -.->|"מצמצם"| certificate_failure
client_certificate -.->|"מחייב"| key_usage
config_externalization -->|"מענה מומלץ ל"| cert_selection
cert_choice_logging -->|"מענה מומלץ ל"| certificate_failure
בתרשים, קו מלא מציין קשר שמתקיים תמיד וקו מקווקו מציין קשר מותנה (תנאי ההתקיימות מפורטים בהסבר של כל קשר בעמוד המפורט). רשימת כל הקשרים (סך הכול 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 פנימית ב«רשויות אישורי שורש מהימנות» במאגר המחשב, הוא יופיע גם ב«רשויות אישורי שורש מהימנות» של כל המשתמשים. ולהפך, רק מאגר «אישי» אינו מורש, ולכן לאישור לקוח (מה ששמים במאגר האישי) צריך להחליט בעצמכם «ממי הוא צריך להיראות». האסימטריה הזו היא גיבורת המאמר כולו.
flowchart TB
accTitle: מאגר המחשב ומאגר המשתמש
accDescr: מאגר המחשב הוא אחד למחשב ומשותף לכל המשתמשים והשירותים, ומאגר המשתמש שונה לכל חשבון ומציג בירושה את תוכן המחשב מלבד «אישי»
subgraph LM["מחשב (LocalMachine)<br/>אחד למחשב, משותף לכל המשתמשים והשירותים"]
LMMY["אישי (My)"]
LMROOT["רשויות אישורי שורש מהימנות (Root)"]
LMCA["רשויות אישור ביניים (CA)"]
LMTP["מפרסמים מהימנים (TrustedPublisher)"]
end
subgraph CU["משתמש (CurrentUser)<br/>שונה לכל חשבון"]
CUMY["אישי (My)<br/>※ אינו מורש = אתם מחליטים לאן לשים"]
CUROOT["רשויות אישורי שורש מהימנות (Root)"]
CUCA["רשויות אישור ביניים (CA)"]
CUTP["מפרסמים מהימנים (TrustedPublisher)"]
end
LMROOT -.->|"נראה בירושת תוכן"| CUROOT
LMCA -.->|"ירושה"| CUCA
LMTP -.->|"ירושה"| CUTP
איור 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. ניתוח התאונה הקלאסית — «בפיתוח עבד, ובהפיכה לשירות לא נמצא»
אפשר לשחזר את התאונה הזו במדויק בשלבים האלה.
- המפתח מייבא pfx בלחיצה כפולה במחשב שלו. ברירת המחדל של האשף היא «המשתמש הנוכחי», ולכן האישור נכנס למאגר המשתמש של חשבון המפתח.
- היישום בפיתוח רץ מ-Visual Studio, כלומר בחשבון המפתח, ולכן פתיחת
StoreLocation.CurrentUserמוצאת את האישור. עובד. - בשרת הייצור רושמים כשירות Windows. השירות רץ כ-NETWORK SERVICE או כחשבון ייעודי.
- ה-
CurrentUserשהקוד של השירות פותח הוא מאגר המשתמש של חשבון הרצת השירות. שם ריק. «האישור לא נמצא».
flowchart TB
accTitle: בפיתוח עבד, וכשירות לא נמצא
accDescr: אישור שהוכנס למאגר המשתמש של המפתח אינו נראה מ-CurrentUser של שירות שרץ בחשבון אחר
subgraph DEV["מכונת פיתוח"]
D1["ייבוא בלחיצה כפולה על pfx<br/>ברירת המחדל באשף היא «המשתמש הנוכחי»"] --> D2["נכנס למאגר המשתמש<br/>של חשבון המפתח"]
D2 --> D3["הרצה מ-Visual Studio<br/>= רץ בחשבון המפתח"]
D3 --> D4["פתיחת CurrentUser מוצאת<br/>→ עובד"]
end
subgraph PROD["שרת ייצור"]
P1["רישום כשירות Windows<br/>חשבון ההרצה הוא NETWORK SERVICE וכו'"] --> P2["ה-CurrentUser שהקוד פותח הוא<br/>מאגר המשתמש של חשבון השירות"]
P2 --> P3["שם ריק<br/>→ «האישור לא נמצא»"]
end
D4 -.->|"מציבים את אותה תוכנית"| P1
איור 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
- פותחים certlm.msc (או snap-in אישורים ליעד חשבון מחשב).
- ב«אישי» → «אישורים» לוחצים ימני על האישור היעד, ומתוך «כל המשימות» פותחים «ניהול מפתחות פרטיים».
- בלשונית «אבטחה» מוסיפים את חשבון ההרצה (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. הליך ההחלפה — תקופת מקביליות ומלכודת טביעת האצבע
עדכון אישור אינו «מוחקים ושמים» אלא «מוסיפים, מחליפים, מאשרים, ואז מוחקים».
- מייבאים את האישור החדש (pfx) לאותו מאגר. טביעת האצבע שונה, ולכן ישן וחדש יכולים לדור יחד באותו מאגר.
- מעניקים הרשאות למפתח הפרטי של האישור החדש (פרק 4). כאן קל לשכוח בעדכון. ההרשאה צמודה לכל מפתח פרטי של אישור, ולכן אחרי החלפת אישור מעניקים מחדש.
- דיווח למערכת היעד (כש-API דורש רישום מראש של האישור) משלימים קודם, תוך המשך תפעול באישור הישן, ומבטיחים תקופת מקביליות שבה גם ישן וגם חדש מתקבלים. אם מחליפים קודם, הצד השני דוחה את האישור החדש והתקשורת בייצור נעצרת.
- מחליפים את תצורת היישום לאישור החדש, ומאשרים פעולה.
- אחרי תקופה מספקת, מוחקים את האישור הישן.
flowchart LR
accTitle: עדכון אישור מוסיפים ואז מחליפים
accDescr: מייבאים pfx חדש לאותו מאגר, מעניקים הרשאות, רושמים מראש אצל היעד, מחליפים טביעת אצבע, ואחרי תקופת המקביליות מוחקים את הישן
I["1. ייבוא pfx חדש לאותו מאגר<br/>(ישן וחדש יחד)"] --> P["2. הענקת הרשאות<br/>למפתח הפרטי של האישור החדש"]
P --> R["3. רישום מראש אצל היעד<br/>(המשך תפעול באישור הישן)"]
R --> SW["4. החלפת טביעת האצבע בתצורה<br/>החלפה ואישור פעולה"]
SW --> DEL["5. אחרי תקופת המקביליות<br/>מחיקת האישור הישן"]
איור 3: סדר החלפת אישור הוא הוספה → הרשאות → רישום מראש → החלפת תצורה → מחיקת הישן; לא לשכוח עדכון טביעת אצבע.
המלכודת הגדולה כאן היא טביעת אצבע שכתובה בקובץ תצורה או בקוד. טביעת אצבע ייחודית לכל אישור, ולכן בעדכון היא תמיד משתנה. אם ולו מקום אחד עדיין מפנה לטביעת האצבע הישנה, מתקבל «עדכנו את האישור ועדיין אי אפשר להתחבר». הדרך הבטוחה היא לנהל בפנקס איפה כתובה טביעת האצבע (תצורת יישום, קישור IIS, סקריפט, דיווח ליעד).
5.3. ההמלצה לפנקס אישורים
פנקס — די בגליון Excel אחד בהתחלה. לכל הפחות עמודות שימוש / מנפיק / נושא / טביעת אצבע / מקום (שם שרת + מאגר) / חשבון עם הרשאת מפתח פרטי / תוקף / קישור להליך עדכון / אחראי, ומצליבים מול תוצאת הספירה ב-5.1. מהות תאונת האישורים אינה בעיית טכנולוגיה אלא בעיית «לאף אחד אין רשימה», ולכן הפנקס הוא מה שהכי עובד.
6. קריאת אימות וכישלון — שרשרת והפצת שורש
6.1. יסודות אימות השרשרת ו-certutil
שגיאות בסגנון «האישור הזה אינו מהימן» הן מצב שבו השרשרת (נתיב ההוכחה) מהאישור הקצה עד CA השורש קרועה איפשהו. לחיתוך נוח certutil.7
flowchart TB
accTitle: שלוש הסיבות הקלאסיות לחיתוך אימות שרשרת
accDescr: אי אפשר להשיג CA ביניים, השורש לא הופץ, או שפג תוקף האישור הקצה, וכל אחד מהם גורם לשגיאת אמון
LEAF["האישור הקצה<br/>(אישור לקוח / אישור שרת)"] --> INT["אישור CA ביניים<br/>מקום: מאגר רשויות אישור ביניים (CA)"]
INT --> ROOT["אישור CA שורש<br/>מקום: רשויות אישורי שורש מהימנות (Root)"]
INT -.->|"אי אפשר להשיג<br/>(לא בהצגה, לא ב-AIA, לא במאגר)"| E1["אי אפשר לבנות שרשרת<br/>(סיבה קלאסית 1)"]
ROOT -.->|"לא הופץ"| E2["שגיאת «אינו מהימן»<br/>(סיבה קלאסית 2)"]
LEAF -.->|"פג תוקף"| E3["שגיאת תקופת תוקף<br/>(סיבה קלאסית 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, ותפעול שמכניס חתימה עצמית לשורש — סביבת בדיקה בלבד, עם תוקף. - בקוד מוציאים טביעת אצבע לתצורה ומשאירים בלוג את האישור שנבחר. זה לבדו משנה את הטיפול בתקלות שמקורן באישור.
מאמרים קשורים
- למה מופיע «Windows הגנה על המחשב»
- שמירת סודות ביישומי Windows — להימנע מתצורה גלויה עם DPAPI
- טיפול בטוח באישורים ב-PowerShell — לגרש סיסמאות גלויות מסקריפטים
- אסור לעטוף HttpClient ב-using — תקשורת HTTP מעשית ביישומים עסקיים ב-C#
- מה קורה כשמעבירים כרטיס ביטוח My Number — קריאת שילוב אימות זכאות מקוון ומערכת קבלות מקוד המקור של ORCA
תחומי ייעוץ קשורים
KomuraSoft LLC מטפלת בפיתוח יישומים עסקיים שמשלבים Web API עם אישור לקוח (API בנקאי, אימות זכאות מקוון וכו’), בחקירת תקלות בסגנון «האישור לא נמצא» ו«אחרי עדכון אי אפשר להתחבר», ובארגון הליך החלפת אישורים. אפשר להתייעץ כבר מהשלב שבו לא ברור איזה מאגר להסתכל עליו.
מקורות
-
Microsoft Learn, Local Machine and Current User Certificate Stores. על כך שמאגר האישורים של המחשב מקומי למחשב ומשותף לכל המשתמשים ונמצא תחת HKEY_LOCAL_MACHINE; על כך שמאגר האישורים של המשתמש הוא לפי חשבון משתמש ונמצא תחת HKEY_CURRENT_USER; ועל כך שמאגר המשתמש יורש את תוכן מאגר המחשב מלבד מאגר «אישי» (אישור שנוסף ל«רשויות אישורי שורש מהימנות» של המחשב מופיע גם באותו מאגר אצל כל משתמש). ↩ ↩2 ↩3 ↩4
-
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
-
Microsoft Learn, How to: View certificates with the MMC snap-in. על כך ש-certlm.msc מנהל אישורים של המכשיר המקומי (המחשב המקומי) ו-certmgr.msc מנהל אישורים של המשתמש הנוכחי; על כך של-snap-in האישורים יש שלושה יעדים: «חשבון מחשב», «חשבון משתמש», «חשבון שירות»; ועל כך שמשתמש שאינו מנהל יכול לנהל רק אישורים של חשבון המשתמש שלו. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, about_Certificate_Provider. על כך שכונן Cert: ב-PowerShell הוא מרחב שמות היררכי עם שני מקומות מאגר, CurrentUser ו-LocalMachine; על כך שאפשר למנות מאגרים ואישורים ב-Get-ChildItem; על כך שהפרמטר -ExpiringInDays מחזיר אישורים שיפקעו בתוך מספר הימים שצוין (0 לשכבר פג); על פרמטרים דינמיים כמו -CodeSigningCert; על כך שתוקף נשמר במאפיין NotAfter; ועל כך שאישורים מזוהים בטביעת אצבע. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, How to Modify Private Key Permissions to Support Management Server or Streaming Server. על ההליך שבו ב-snap-in אישורים ליעד מאגר המחשב המקומי פותחים «ניהול מפתחות פרטיים» (Manage Private Keys), ובלשונית «אבטחה» מוסיפים הרשאת «קריאה» לחשבון הרצת השירות (למשל Network Service). ↩ ↩2 ↩3
-
Microsoft Learn, Import-PfxCertificate. על כך ש-Import-PfxCertificate מייבא אישור ומפתח פרטי מקובץ PFX למאגר שצוין; על כך שאם לא מציינים את המתג -Exportable אי אפשר לייצא את המפתח הפרטי שיובא; ועל התחביר ודוגמאות השימוש בפרמטרים -CertStoreLocation, -Password, -FilePath. ↩ ↩2 ↩3
-
Microsoft Learn, certutil. על כך ש-certutil -verify מאמת אישור, CRL ושרשרת אישורים, ושבלי ציון קובץ אישור CA הוא בונה שרשרת מלאה ומאמת; על זמינות האפשרות -urlfetch; ועל כך ש-certutil -store עושה dump למאגר אישורים, ושעם האפשרות -user ניגשים למאגר המשתמש במקום למאגר המחשב. ↩ ↩2
-
Microsoft Learn, Distribute Certificates to Client Computers by Using Group Policy. על ההליך לייבא אישור ל«רשויות אישורי שורש מהימנות» תחת «תצורת מחשב\מדיניות\הגדרות Windows\הגדרות אבטחה\מדיניות מפתח ציבורי» ב-Group Policy ולהפיץ למחשבי לקוח בדומיין, ועל ההרשאות הנדרשות (ברמה של Domain Admins / Enterprise Admins). ↩
-
Microsoft Learn, Create trusted certificate profiles in Microsoft Intune. על כך שפרופיל «אישור מהימן» ב-Intune הוא מנגנון להפצת אישור CA שורש או ביניים למכשירים מנוהלים; על כך שהוא משמש כהנחה לפרופילי אישור SCEP/PKCS כדי לבסס אמון ב-CA השורש; ועל כך שב-Windows אפשר לבחור כמאגר יעד «מאגר אישורי מחשב — שורש», «מאגר אישורי מחשב — ביניים», «מאגר אישורי משתמש — ביניים». ↩
-
Microsoft Learn, X509Store Class. על כך שאפשר לבנות X509Store עם StoreName ו-StoreLocation (CurrentUser / LocalMachine), לפתוח מאגר בשיטת Open וב-OpenFlags (ReadOnly, OpenExistingOnly וכו’), ולהשיג אוסף אישורים במאפיין Certificates; על כך ששמות המאגר הסטנדרטיים כוללים My, Root, CA, TrustedPublisher וכו’; ועל כך שמאגר TrustedPublisher קיים גם ב-CurrentUser וגם ב-LocalMachine. ↩ ↩2
-
Microsoft Learn, X509Certificate2Collection.Find(X509FindType, Object, Boolean) Method. על כך ששיטת Find מחפשת אישורים לפי X509FindType (FindByThumbprint וכו’) וערך חיפוש; ועל כך שכשמציינים true בארגומנט השלישי validOnly מוחזרים רק אישורים תקפים שעברו אימות. ↩ ↩2
-
Microsoft Learn, HttpClientHandler.ClientCertificates Property. על כך שמאפיין ClientCertificates הוא X509CertificateCollection שמוצג לשרת באימות לקוח מבוסס-אישור; ועל כך שב-.NET Core, אם לאישור יש מאפיין שימוש במפתח, נדרש שיכלול «Digital Signature». ↩ ↩2
מאמרים קשורים
מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.
חומת האש של Windows ויישומים עסקיים — רישום כללי כניסה מהמתקין
הסיבה הקלאסית ל«במכונת הפיתוח עובד, ואצל הלקוח אי אפשר לתקשר» היא חומת האש של Windows. המאמר מסביר חסימת כניסה כברירת מחדל ופרופילים, למה...
מדיניות ביקורת אבטחה ב-Windows וחקירת יומן אירועים בפועל — איך להפוך לצוות IT שיודע לקרוא את 4625
מדריך מעשי למענה על «בדקו את יומני הכניסה שנכשלו». הוא מכסה את הקשר בין מדיניות ביקורת בסיסית למתקדמת, תת-הקטגוריות שכדאי להפעיל לפחות, א...
מדריך מעשי ל-Windows LAPS — להפסיק סיסמת מנהל מקומית משותפת לכל המחשבים
סיסמת מנהל מקומית משותפת לכל המחשבים היא כר פורה ל-Pass-the-Hash: פריצה למחשב אחד מתפשטת לכל השאר. המאמר מסביר את הסיבוב האוטומטי ב-Windo...
קבצי OneDrive לפי דרישה ויישומים עסקיים — ההנחות שממלאי מקום שוברים וכיצד להתמודד
קובץ CSV בשולחן העבודה לא נפתח, או שייבוא נכשל ב־"הקובץ לא נמצא" — הסיבה עשויה להיות Known Folder Move וקבצים לפי דרישה של OneDrive. המאמ...
עותק צל של כרך (VSS): המנגנון והפרקטיקה — למה תוכנת גיבוי מצליחה להעתיק קבצים שעדיין בשימוש
קבצים שבשימוש בדרך כלל אי אפשר להעתיק בגלל הפרת שיתוף — אז איך תוכנת גיבוי מצליחה? המאמר מסביר את תפקידי המבקש, הכותב והספק בשירות Volume...
נושאים קשורים
העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.
נושאים טכניים ב-Windows
שער לנושאי פיתוח Windows, חקירת תקלות וניצול נכסים קיימים.
שירותים הקשורים לנושא הזה
המאמר קשור ישירות לשירותים הבאים.
פיתוח יישומי Windows
יישומים עסקיים, חיבור התקנים וכלי תקשורת, מהגדרת הדרישות ועד הפיתוח.
שאלות נפוצות
שאלות נפוצות בפניות בנושא המאמר.
- מה ההבדל בין 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 מחזיר אישורים שכבר פג תוקפם. מריצים את זה מדי חודש על כל השרתים ומצליבים מול פנקס האישורים — ורוב תאונות «בבוקר אי אפשר להתחבר כי פג התוקף» נמנעות.