השתמש ב- Char Array Over a String לניהול סיסמאות ב- Java?

1. סקירה כללית

במאמר זה נסביר מדוע עלינו להשתמש לְהַשְׁחִיר[] מערך לייצוג סיסמאות במקום חוּט בג'אווה.

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

אנו מניחים גם שאיננו יכולים לשלוט בפורמט הסיסמה (למשל הסיסמה מגיעה מממשק ה- API של הצד השלישי בצורה של ה- חוּט). למרות שזה נראה ברור להשתמש בחפץ מסוג מיתר לצורך ניהול סיסמאות, מומלץ להשתמש בצוות Java עצמו לְהַשְׁחִיר[] במקום זאת.

למשל, אם נסתכל על ה- JPasswordField שֶׁל javax.swing, אנו יכולים לראות כי השיטה getText () אשר חוזר חוּט הוצא משימוש מאז Java 2 והוא מוחלף על ידי קבל סיסמא() שיטה שחוזרת לְהַשְׁחִיר[].

אז בואו נחקור כמה סיבות חזקות מדוע זה המקרה.

2. מיתרים בלתי ניתנים לשינוי

חוּטניתן לשנות את הג'אווה ב- Java, כלומר איננו יכולים לשנות אותם באמצעות ממשקי API ברמה גבוהה. כל שינוי ב- חוּט אובייקט יפיק חדש חוּט, לשמור את הזקן בזיכרון.

לכן, הסיסמה המאוחסנת ב- חוּט יהיה זמין בזיכרון עד ש- Garbage Collector ינקה אותו. איננו יכולים לשלוט מתי זה קורה, אך תקופה זו יכולה להיות ארוכה משמעותית מאשר עבור אובייקטים רגילים מאז מיתרים נשמרים בבריכת מיתרים לצורך שימוש חוזר.

כתוצאה מכך, כל מי שיש לו גישה לפח הזיכרון יכול לשלוף את הסיסמה מהזיכרון.

עם לְהַשְׁחִיר[] מערך במקום חוּט, אנו יכולים למחוק נתונים במפורש לאחר שנסיים בעבודה המיועדת. בדרך זו, אנו נבטיח כי הסיסמה תוסר מהזיכרון עוד לפני איסוף האשפה.

בואו נסתכל כעת על קטעי קוד, המדגימים את מה שדנו זה עתה.

ראשון עבור חוּט:

System.out.print ("ערך סיסמת מחרוזת מקורית:"); System.out.println (stringPassword); System.out.println ("hashCode סיסמת מחרוזת מקורית:" + Integer.toHexString (stringPassword.hashCode ())); מחרוזת newString = "********"; stringPassword.replace (stringPassword, newString); System.out.print ("ערך סיסמת מחרוזת לאחר שניסה להחליף אותה:"); System.out.println (stringPassword); System.out.println ("hashCode לאחר שניסה להחליף את המחרוזת המקורית:" + Integer.toHexString (stringPassword.hashCode ()));

התפוקה תהיה:

ערך סיסמת מחרוזת מקורית: סיסמה סיסמת מחרוזת מקורית hashCode: 4889ba9b ערך מחרוזת לאחר שניסה להחליף אותה: סיסמת hashCode לאחר ניסיון להחליף את המחרוזת המקורית: 4889ba9b

עכשיו בשביל לְהַשְׁחִיר[]:

char [] charPassword = char חדש [] {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; System.out.print ("ערך סיסמת המקור של char char:"); System.out.println (charPassword); System.out.println ("hashCode הסיסמה המקורית של char:" + Integer.toHexString (charPassword.hashCode ())); Arrays.fill (charPassword, '*'); System.out.print ("ערך סיסמת char שונה:"); System.out.println (charPassword); System.out.println ("hashCode של סיסמת char שונה:" + Integer.toHexString (charPassword.hashCode ()));

התפוקה היא:

ערך סיסמא מקורי של char: סיסמה hash קוד סיסמא מקורי: 7cc355be ערך סיסמת char שונה: ******** hash שונה של סיסמת char שונה: 7cc355be

כפי שאנו רואים, לאחר שניסינו להחליף את תוכן המקור חוּט, הערך נשאר זהה ו hashCode () השיטה לא החזירה ערך שונה באותה ביצוע של היישום, כלומר המקור חוּט נשאר שלם.

ובשביל לְהַשְׁחִיר[] מערך, הצלחנו לשנות את הנתונים באותו אובייקט.

3. אנו יכולים בטעות להדפיס סיסמאות

יתרון נוסף בעבודה עם סיסמאות ב- לְהַשְׁחִיר[] מערך הוא מניעה של רישום בטעות של הסיסמה בקונסולות, צגים או במקומות אחרים חסרי ביטחון פחות או יותר.

בואו נבדוק את הקוד הבא:

String passwordString = "סיסמה"; char [] passwordArray = char חדש [] {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; System.out.println ("הדפסת סיסמת מחרוזת ->" + passwordString); System.out.println ("הדפסת סיסמת char [] ->" + passwordArray);

עם הפלט:

סיסמת מחרוזת הדפסה -> סיסמא הדפסת סיסמה [] סיסמה -> [[מוגן בדוא"ל]

אנו רואים שהתוכן עצמו מודפס במקרה הראשון, בעוד שבמקרה השני הנתונים אינם כל כך שימושיים, מה שהופך אותו לְהַשְׁחִיר[] פחות פגיעים.

4. מסקנה

במאמר מהיר זה הדגשנו כמה סיבות מדוע איננו צריכים להשתמש חוּטs לאיסוף סיסמאות ומדוע עלינו להשתמש לְהַשְׁחִיר[] במקום זאת מערכים.

כמו תמיד, ניתן למצוא קטעי קוד ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found