為什么存儲(chǔ)密碼字符數(shù)組比字符串更合適?
“為什么存儲(chǔ)密碼用字符數(shù)組比字符串更合適”這個(gè)問(wèn)題是我的一個(gè)朋友在最近一次面試中提到的。那哥們應(yīng)聘的是一個(gè)技術(shù)lead職位,有超過(guò)六年的工作經(jīng)驗(yàn)。字符數(shù)組和字符串都可以用于存儲(chǔ)文本數(shù)據(jù),但是在選擇具體哪一種時(shí),如果你沒(méi)有針對(duì)具體的情況是很難回答這個(gè)問(wèn)題的。但是正如這哥們說(shuō)的任何與字符串相關(guān)的問(wèn)題一定可以從字符串的屬性里面的線索中找到,比如不可變性。他就用這種方式去說(shuō)服面試官的。這里我們就來(lái)探討一些關(guān)于為什么你應(yīng)該使用char[] 來(lái)存儲(chǔ)密碼而不是字符串。
1. 因?yàn)樽址遣豢勺儗?duì)象,如果作為普通文本存儲(chǔ)密碼,那么它會(huì)一直存在內(nèi)存中直至被垃圾收集器回收。因?yàn)樽址畯淖址刂腥〕龅模ㄈ绻刂杏性撟址椭苯訌某刂蝎@取,否則new 一個(gè)出來(lái),然后把它放入池中),這樣有很大的機(jī)會(huì)長(zhǎng)期保留在內(nèi)存中,這樣會(huì)引發(fā)安全問(wèn)題。
因?yàn)槿魏慰梢栽L問(wèn)內(nèi)存的人能以明碼的方式把密碼dump出來(lái)。另外你還應(yīng)該始終以加密而不是普通的文本來(lái)表示密碼。因?yàn)樽址遣豢勺儯虼藳](méi)有任何方法可以改變其內(nèi)容,任何改變都將產(chǎn)生一個(gè)新的字符串,而如果使用char[],你就可以設(shè)置所有的元素為空或者為零(這里作者的意思是說(shuō),讓認(rèn)證完后該數(shù)組不再使用了,就可以用零或者null覆蓋原來(lái)的密碼,防止別人從內(nèi)存中dump出來(lái))。所以存儲(chǔ)密碼用字符數(shù)組可以明顯的減輕密碼被盜的危險(xiǎn)。
2. Java官方本身也推薦字符數(shù)組,JpasswordField的方法getPassword()就是返回一個(gè)字符數(shù)組,而由于安全原因getText()方法是被廢棄掉的,因?yàn)樗祷匾粋€(gè)純文本字符串。跟隨Java 團(tuán)隊(duì)的步伐吧,沒(méi)有錯(cuò)。
3. 字符串以普通文本打印在在log文件或控制臺(tái)中也易引起危險(xiǎn),但是如果使用數(shù)組你不能打印數(shù)組的內(nèi)容,而是它的內(nèi)存地址。盡管這不是它的真正原因,但仍值得注意。
String strPassword="Unknown";
char[] charPassword= new char[]{'U','n','k','w','o','n'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);
String password: Unknown
Character password: [C@110b053
以上所有就是為什么字符數(shù)組比字符串保存密碼要好的原因,盡管使用char[]還不足以安全。我同樣建議你用hash或者密碼加密代替普通文本,而且一旦認(rèn)證完成盡可能快的把他清除掉。