一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java面試題沖刺第二十六天--實戰編程

Java面試題沖刺第二十六天--實戰編程

2021-12-07 13:19_陳哈哈 Java教程

這篇文章主要為大家分享了最有價值的三道java實戰面試題,涵蓋內容全面,包括數據結構和算法相關的題目、經典面試編程題等,感興趣的小伙伴們可以參考一下

 

面試題1:你們是怎樣保存用戶密碼等敏感數據的?

本題回答參考朱曄的《Java業務開發常見錯誤100例》

Java面試題沖刺第二十六天--實戰編程

我們知道,用戶名、密碼、身份證等都屬于用戶敏感信息,其中最敏感的數據恐怕就是用戶的密碼了。黑客一旦竊取了用戶密碼,就可以登錄進用戶的賬號,消耗其資產、發布不良信息等;更可怕的是,有些用戶至始至終都是使用一套密碼,密碼一旦泄露,就可以被黑客通過撞庫來登錄全網各大平臺,嘿嘿嘿。

為了防止密碼泄露,最重要的原則是不要在數據庫保存用戶原始密碼。

大家經常說,不要明文保存用戶密碼,應該把密碼通過 MD5 加密后保存。這的確是一個正確的方向,但這個說法并不準確。

首先,MD5 其實不是真正的加密算法。所謂加密算法,是可以使用密鑰把明文加密為密文,隨后還可以使用密鑰解密出明文,是雙向的。而 MD5 是散列、哈希算法或者摘要算法。不管多長的數據,使用 MD5 運算后得到的都是固定長度的摘要信息或指紋信息,無法再解密為原始數據。所以,MD5 是單向的。最重要的是,僅僅使用 MD5 對密碼進行摘要,并不安全。

比如,使用如下代碼在保持用戶信息時,對密碼進行了 MD5 計算:

UserData userData = new UserData();
userData.setId(1L);
userData.setName(name);
//密碼字段使用MD5哈希后保存
userData.setPassword(DigestUtils.md5Hex(password));
return userRepository.save(userData);

通過輸出,可以看到密碼是 32 位的 MD5:

"password": "325a2cc052914ceeb8c19016c091d2ac"

然后,再去破解網站試一下這個 MD5,就可以得到原始密碼是 salt,也就知道了鹽值是 salt:

其實,知道鹽是什么沒什么關系,關鍵的是我們是在代碼里寫死了鹽,并且鹽很短、所有用戶都是這個鹽。這么做就會有三個問題:

  • 因為鹽太短、太簡單了,如果用戶原始密碼也很簡單,那么整個拼起來的密碼也很短,這樣一般的 MD5 破解網站都可以直接解密這個 MD5,除去鹽就是原始密碼了。
  • 相同的鹽,意味著使用相同密碼的用戶 MD5 值是一樣的,知道了一個用戶的密碼就可能知道了多個。
  • 黑客也可以使用這個鹽來構建一張彩虹表,也就是字典表,雖然會花不少代價,但是一旦構建完成,所有人的密碼都可以被破解。

所以,最好是每一個密碼都有獨立的鹽,并且鹽要長一點,比如超過 20 位。

第二,雖然說每個人的鹽最好不同,但也不建議將一部分用戶數據作為鹽。比如,使用用戶名作為鹽:

userData.setPassword(DigestUtils.md5Hex(name + password));

如果世界上所有的系統都是按照這個方案來保存密碼,那么 root、admin 這樣的用戶使用再復雜的密碼也總有一天會被破解,因為黑客們完全可以針對這些常用用戶名來做彩虹表。所以,鹽最好是隨機的值,并且是全球唯一的,意味著全球不可能有現成的彩虹表給你用。

正確的做法是,使用全球唯一的、和用戶無關的、足夠長的隨機值作為鹽。比如,可以使用 UUID 作為鹽,把鹽一起保存到數據庫中:

userData.setSalt(UUID.randomUUID().toString());
userData.setPassword(DigestUtils.md5Hex(userData.getSalt() + password));

并且每次用戶修改密碼的時候都重新計算鹽,重新保存新的密碼。

需要注意的是,這么做雖然黑客已經很難通過彩虹表來破解密碼了,但是仍然有可能暴力破解密碼,也就是對于同一個用戶名使用常見的密碼逐一嘗試登錄。因此,除了做好密碼哈希保存的工作外,我們還要建設一套完善的安全防御機制,在感知到暴力破解危害的時候,開啟短信驗證、圖形驗證碼、賬號暫時鎖定等防御機制來抵御暴力破解。

那么姓名和身份證又是怎么保存的?

我們把姓名和身份證,叫做二要素。

現在互聯網非常發達,很多服務都可以在網上辦理,很多網站僅僅依靠二要素來確認你是誰。所以,二要素是比較敏感的數據,如果在數據庫中明文保存,那么數據庫被攻破后,黑客就可能拿到大量的二要素信息。如果這些二要素被用來申請貸款等,后果不堪設想。

之前我們提到的單向散列算法(MD5),顯然不適合用來加密保存二要素,因為數據無法解密。這個時候,我們需要選擇真正的加密算法。可供選擇的算法,包括對稱加密和非對稱加密算法兩類。

  • 對稱加密算法:是使用相同的密鑰進行加密和解密。使用對稱加密算法來加密雙方的通信的話,雙方需要先約定一個密鑰,加密方才能加密,接收方才能解密。如果密鑰在發送的時候被竊取,那么加密就是白忙一場。因此,這種加密方式的特點是,加密速度比較快,但是密鑰傳輸分發有泄露風險。

Java面試題沖刺第二十六天--實戰編程

  • 非對稱加密算法:或者叫公鑰密碼算法。公鑰密碼是由一對密鑰對構成的,使用公鑰或者說加密密鑰來加密,使用私鑰或者說解密密鑰來解密,公鑰可以任意公開,私鑰不能公開。使用非對稱加密的話,通信雙方可以僅分享公鑰用于加密,加密后的數據沒有私鑰無法解密。因此,這種加密方式的特點是,加密速度比較慢,但是解決了密鑰的配送分發安全問題。

Java面試題沖刺第二十六天--實戰編程

但是,對于保存敏感信息的場景來說,加密和解密都是我們的服務端程序,不太需要考慮密鑰的分發安全性,也就是說使用非對稱加密算法沒有太大的意義。我們一般會使用對稱加密算法來加密數據。常見的對稱加密算法有:DES、3DES 和 AES。

Java面試題沖刺第二十六天--實戰編程

 

面試題2:怎么控制用戶請求的冪等性的?

冪等性:對于同一筆業務操作,不管調用多少次,得到的結果都是一樣的。

當然,有些操作是天然冪等的,如:

  • 查詢操作:查詢一次和查詢多次,在數據不變的情況下,查詢結果是一樣的。select是天然的冪等操作;
  • 刪除操作:刪除操作也是冪等的,刪除一次和多次刪除都是把數據刪除。

后臺控制冪等性的幾種途徑:

 

1.設置唯一索引:防止新增臟數據

比如支付寶的資金賬戶,支付寶也有用戶賬戶,每個用戶只能有一個資金賬戶,怎么防止給用戶創建資金賬戶多個,那么給資金賬戶表中的用戶ID加唯一索引,所以一個用戶新增成功一個資金賬戶記錄。要點:唯一索引或唯一組合索引來防止新增數據存在臟數據(當表存在唯一索引,并發時新增報錯時,再查詢一次就可以了,數據應該已經存在了,返回結果即可);

 

2.token機制:防止頁面重復提交

原理上通過session token來實現的(也可以通過redis來實現)。當客戶端請求頁面時,服務器會生成一個隨機數Token,并且將Token放置到session當中,然后將Token發給客戶端(一般通過構造hidden表單)。下次客戶端提交請求時,Token會隨著表單一起提交到服務器端。

服務器端第一次驗證相同過后,會將session中的Token值更新下,若用戶重復提交,第二次的驗證判斷將失敗,因為用戶提交的表單中的Token沒變,但服務器端session中Token已經改變了。

 

3.悲觀鎖

獲取數據的時候加鎖獲取。

select * from table_xxx where id="xxx" for update;

注意:id字段一定是主鍵或者唯一索引,不然是鎖表,會死人的;悲觀鎖使用時一般伴隨事務一起使用,數據鎖定時間可能會很長,根據實際情況選用;

 

4.樂觀鎖

樂觀鎖只是在更新數據那一刻鎖表,其他時間不鎖表,所以相對于悲觀鎖,效率更高。樂觀鎖的實現方式多種多樣,可以通過version或者其他狀態條件判斷:

  • 通過版本號實現

update table_xxx set name=#name#,version=version+1 where version=#version#;

  • 通過條件限制

update table_xxx set avai_amount=avai_amount where avai_amount >= 0

 

5.分布式鎖

如果是分布式系統,構建全局唯一索引比較困難,例如唯一性的字段沒法確定,這時候可以引入分布式鎖,通過第三方的系統(redis或zookeeper),在業務系統插入數據或者更新數據,獲取分布式鎖,然后做操作,之后釋放鎖,這樣其實是把多線程并發的鎖的思路,引入多多個系統,也就是分布式系統中得解決思路。

要點:某個長流程處理過程要求不能并發執行,可以在流程執行之前根據某個標志(用戶ID+后綴等)獲取分布式鎖,其他流程執行時獲取鎖就會失敗,也就是同一時間該流程只能有一個能執行成功,執行完成后,釋放分布式鎖(分布式鎖要第三方系統提供);

 

面試題3:你們是如何預防SQL注入問題的?

SQL注入攻擊的總體思路

  • 尋找到SQL注入的位置
  • 判斷服務器類型和后臺數據庫類型
  • 針對不通的服務器和數據庫特點進行SQL注入攻擊

 

預防方式:

 

1、PreparedStatement(簡單有效)

采用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。

sql注入只對sql語句的準備(編譯)過程有破壞作用,而PreparedStatement在執行階段只是把輸入串作為數據處理,不再對sql語句進行解析,因此也就避免了sql注入問題。

 

2、使用正則表達式過濾傳入的參數

要引入的包:

import java.util.regex.*;

正則表達式:

private String CHECKSQL =^(.+)sands(.+)|(.+)sor(.+)s$”;

判斷是否匹配:

Pattern.matches(CHECKSQL,targerStr);

下面是常用來過濾參數是否存在SQL注入的正則表達式:

  • 檢測SQL meta-characters的正則表達式 : /(\%27)|(")|(--)|(\%23)|(#)/ix
  • 修正檢測SQL meta-characters的正則表達式 : /((\%3D)|(=))[^ ]*((\%27)|(")|(--)|(\%3B)|(:))/i
  • 典型的SQL 注入攻擊的正則表達式 : /w*((\%27)|("))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
  • 檢測SQL注入,UNION查詢關鍵字的正則表達式 : /((\%27)|("))union/ix(\%27)|(")

 

3.使用正則表達式過濾傳入的URL

比較通用的一個方法,jsp中調用該函數檢查是否包函非法字符,防止SQL從URL注入:

(||之間的參數可以根據自己程序的需要添加)

public static boolean sql_inj(String str){
    String inj_str = ""|and|exec|insert|select|delete|update|
    count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
    String inj_stra[] = split(inj_str,"|");
    for (int i=0 ; i < inj_stra.length ; i++ ){
        if (str.indexOf(inj_stra[i])>=0){
        return true;
        }
    }
    return false;
}

 

總結

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/qq_39390545/article/details/119790208

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
主站蜘蛛池模板: 亚洲国产综合自在线另类 | 99热6这里只有精品 99欧美精品 | 亚洲欧美专区精品伊人久久 | 欧美一区二区不卡视频 | 免费369看片入口 | 久久久精品免费视频 | 久久亚洲午夜牛牛影视 | 亚洲日本免费 | 国产高清免费午夜在线视频 | 丫鬟粗大狠狠贯穿h | 日本漫画无翼乌 | 99热国产在线 | 欧美影院天天5g天天爽 | 亚洲黄色免费在线观看 | 亚洲国产天堂久久综合网站 | 国产午夜精品久久理论片小说 | 精品久久久久久亚洲精品 | 秋霞在线一级 | 欧美一区二区视频 | 岛国a香蕉片不卡在线观看 荡女淫春2古装 | 丝袜足控免费网站xx动漫漫画 | 精品无人区麻豆乱码1区2 | 把美女屁股眼扒开图片 | 91热爆在线| 欧美一区二区三区四区视频 | 牛牛色婷婷在线视频播放 | 999久久久 | 亚洲网视频 | 国产色视频网站 | 亚洲mv国产精品mv日本mv | 精品性久久| 性吟网| 97热在线| 日韩视频免费一区二区三区 | 乌克兰17一18处交 | 亚洲天堂视频在线观看 | 国产丰满美女做爰 | 国产一区二区三区免费在线视频 | 日本嫩交 | 欧美人禽杂交狂配无删完整 | 鬼吹灯之天星术免费观看 |