㈠ md5 演算法程序+詳細注釋,高分求教!
MD5加密演算法簡介
一、綜述
MD5的全稱是message-digest algorithm 5(信息-摘要演算法),在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest開發出來,經md2、md3和md4發展而來。它的作用是讓大容量信息在用數字簽名軟體簽署私人密匙前被"壓縮"成一種保密的格式(就是把一 個任意長度的位元組串變換成一定長的大整數)。不管是md2、md4還是md5,它們都需要獲得一個隨機長度的信息並產生一個128位的信息摘要。雖然這些 演算法的結構或多或少有些相似,但md2的設計與md4和md5完全不同,那是因為md2是為8位機器做過設計優化的,而md4和md5卻是面向32位的電 腦。這三個演算法的描述和c語言源代碼在internet rfcs 1321中有詳細的描述(http://www.ietf.org/rfc/rfc1321.txt),這是一份最權威的文檔,由ronald l. rivest在1992年8月向ieft提交。
rivest在1989年開發出md2演算法。在這個演算法中,首先對信 息進行數據補位,使信息的位元組長度是16的倍數。然後,以一個16位的檢驗和追加到信息末尾。並且根據這個新產生的信息計算出散列值。後來,rogier 和chauvaud發現如果忽略了檢驗和將產生md2沖突。md2演算法的加密後結果是唯一的--既沒有重復。
為了加強演算法的安全性, rivest在1990年又開發出md4演算法。md4演算法同樣需要填補信息以確保信息的位元組長度加上448後能被512整除(信息位元組長度mod 512 = 448)。然後,一個以64位二進製表示的信息的最初長度被添加進來。信息被處理成512位damg?rd/merkle迭代結構的區塊,而且每個區塊要 通過三個不同步驟的處理。den boer和bosselaers以及其他人很快的發現了攻擊md4版本中第一步和第三步的漏洞。dobbertin向大家演示了如何利用一部普通的個人電 腦在幾分鍾內找到md4完整版本中的沖突(這個沖突實際上是一種漏洞,它將導致對不同的內容進行加密卻可能得到相同的加密後結果)。毫無疑問,md4就此 被淘汰掉了。
盡管md4演算法在安全上有個這么大的漏洞,但它對在其後才被開發出來的好幾種信息安全加密演算法的出現卻有著不可忽視的引導作用。除了md5以外,其中比較有名的還有sha-1、ripe-md以及haval等。
一年以後,即1991年,rivest開發出技術上更為趨近成熟的md5演算法。它在md4的基礎上增加了"安全-帶子"(safety-belts)的 概念。雖然md5比md4稍微慢一些,但卻更為安全。這個演算法很明顯的由四個和md4設計有少許不同的步驟組成。在md5演算法中,信息-摘要的大小和填充 的必要條件與md4完全相同。den boer和bosselaers曾發現md5演算法中的假沖突(pseudo-collisions),但除此之外就沒有其他被發現的加密後結果了。
van oorschot和wiener曾經考慮過一個在散列中暴力搜尋沖突的函數(brute-force hash function),而且他們猜測一個被設計專門用來搜索md5沖突的機器(這台機器在1994年的製造成本大約是一百萬美元)可以平均每24天就找到一 個沖突。但單從1991年到2001年這10年間,竟沒有出現替代md5演算法的md6或被叫做其他什麼名字的新演算法這一點,我們就可以看出這個瑕疵並沒有 太多的影響md5的安全性。上面所有這些都不足以成為md5的在實際應用中的問題。並且,由於md5演算法的使用不需要支付任何版權費用的,所以在一般的情 況下(非絕密應用領域。但即便是應用在絕密領域內,md5也不失為一種非常優秀的中間技術),md5怎麼都應該算得上是非常安全的了。
二、演算法的應用
md5的典型應用是對一段信息(message)產生信息摘要(message-digest),以防止被篡改。比如,在unix下有很多軟體在下載的時候都有一個文件名相同,文件擴展名為.md5的文件,在這個文件中通常只有一行文本,大致結構如:
md5 (tanajiya.tar.gz) =
這就是tanajiya.tar.gz文件的數字簽名。md5將整個文件當作一個大文本信息,通過其不可逆的字元串變換演算法,產生了這個唯一的md5信 息摘要。如果在以後傳播這個文件的過程中,無論文件的內容發生了任何形式的改變(包括人為修改或者下載過程中線路不穩定引起的傳輸錯誤等),只要你對這個 文件重新計算md5時就會發現信息摘要不相同,由此可以確定你得到的只是一個不正確的文件。如果再有一個第三方的認證機構,用md5還可以防止文件作者的 "抵賴",這就是所謂的數字簽名應用。
md5還廣泛用於加密和解密技術上。比如在unix系統中用戶的密碼就是以md5(或其它類似的算 法)經加密後存儲在文件系統中。當用戶登錄的時候,系統把用戶輸入的密碼計算成md5值,然後再去和保存在文件系統中的md5值進行比較,進而確定輸入的 密碼是否正確。通過這樣的步驟,系統在並不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統的合法性。這不但可以避免用戶的密碼被具有系統管理員許可權的 用戶知道,而且還在一定程度上增加了密碼被破解的難度。
正是因為這個原因,現在被黑客使用最多的一種破譯密碼的方法就是一種被稱為"跑字 典"的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字元串表,另一種是用排列組合方法生成的,先用md5程序計算出這些字典項的md5值,然後 再用目標的md5值在這個字典中檢索。我們假設密碼的最大長度為8位位元組(8 bytes),同時密碼只能是字母和數字,共26+26+10=62個字元,排列組合出的字典的項數則是p(62,1)+p(62,2)….+p (62,8),那也已經是一個很天文的數字了,存儲這個字典就需要tb級的磁碟陣列,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼md5值的情況 下才可以。這種加密技術被廣泛的應用於unix系統中,這也是為什麼unix系統比一般操作系統更為堅固一個重要原因。
三、演算法描述
對md5演算法簡要的敘述可以為:md5以512位分組來處理輸入的信息,且每一分組又被劃分為16個32位子分組,經過了一系列的處理後,演算法的輸出由四個32位分組組成,將這四個32位分組級聯後將生成一個128位散列值。
在md5演算法中,首先需要對信息進行填充,使其位元組長度對512求余的結果等於448。因此,信息的位元組長度(bits length)將被擴展至n*512+448,即n*64+56個位元組(bytes),n為一個正整數。填充的方法如下,在信息的後面填充一個1和無數個 0,直到滿足上面的條件時才停止用0對信息的填充。然後,在在這個結果後面附加一個以64位二進製表示的填充前信息長度。經過這兩步的處理,現在的信息字 節長度=n*512+448+64=(n+1)*512,即長度恰好是512的整數倍。這樣做的原因是為滿足後面處理中對信息長度的要求。
md5中有四個32位被稱作鏈接變數(chaining variable)的整數參數,他們分別為:a=0x01234567,b=0x89abcdef,c=0xfedcba98,d=0x76543210。
當設置好這四個鏈接變數後,就開始進入演算法的四輪循環運算。循環的次數是信息中512位信息分組的數目。
將上面四個鏈接變數復制到另外四個變數中:a到a,b到b,c到c,d到d。
主循環有四輪(md4隻有三輪),每輪循環都很相似。第一輪進行16次操作。每次操作對a、b、c和d中的其中三個作一次非線性函數運算,然後將所得結 果加上第四個變數,文本的一個子分組和一個常數。再將所得結果向右環移一個不定的數,並加上a、b、c或d中之一。最後用該結果取代a、b、c或d中之 一。
以一下是每次操作中用到的四個非線性函數(每輪一個)。
f(x,y,z) =(x&y)|((~x)&z)
g(x,y,z) =(x&z)|(y&(~z))
h(x,y,z) =x^y^z
i(x,y,z)=y^(x|(~z))
(&是與,|是或,~是非,^是異或)
這四個函數的說明:如果x、y和z的對應位是獨立和均勻的,那麼結果的每一位也應是獨立和均勻的。
f是一個逐位運算的函數。即,如果x,那麼y,否則z。函數h是逐位奇偶操作符。
假設mj表示消息的第j個子分組(從0到15),
<< ff(a,b,c,d,mj,s,ti) 表示 a=b+((a+(f(b,c,d)+mj+ti)
<< gg(a,b,c,d,mj,s,ti) 表示 a=b+((a+(g(b,c,d)+mj+ti)
<< hh(a,b,c,d,mj,s,ti) 表示 a=b+((a+(h(b,c,d)+mj+ti)
<< ii(a,b,c,d,mj,s,ti) 表示 a=b+((a+(i(b,c,d)+mj+ti)
<< 這四輪(64步)是:
第一輪
ff(a,b,c,d,m0,7,0xd76aa478)
ff(d,a,b,c,m1,12,0xe8c7b756)
ff(c,d,a,b,m2,17,0x242070db)
ff(b,c,d,a,m3,22,0xc1bdceee)
ff(a,b,c,d,m4,7,0xf57c0faf)
ff(d,a,b,c,m5,12,0x4787c62a)
ff(c,d,a,b,m6,17,0xa8304613)
ff(b,c,d,a,m7,22,0xfd469501)
ff(a,b,c,d,m8,7,0x698098d8)
ff(d,a,b,c,m9,12,0x8b44f7af)
ff(c,d,a,b,m10,17,0xffff5bb1)
ff(b,c,d,a,m11,22,0x895cd7be)
ff(a,b,c,d,m12,7,0x6b901122)
ff(d,a,b,c,m13,12,0xfd987193)
ff(c,d,a,b,m14,17,0xa679438e)
ff(b,c,d,a,m15,22,0x49b40821)
第二輪
gg(a,b,c,d,m1,5,0xf61e2562)
gg(d,a,b,c,m6,9,0xc040b340)
gg(c,d,a,b,m11,14,0x265e5a51)
gg(b,c,d,a,m0,20,0xe9b6c7aa)
gg(a,b,c,d,m5,5,0xd62f105d)
gg(d,a,b,c,m10,9,0x02441453)
gg(c,d,a,b,m15,14,0xd8a1e681)
gg(b,c,d,a,m4,20,0xe7d3fbc8)
gg(a,b,c,d,m9,5,0x21e1cde6)
gg(d,a,b,c,m14,9,0xc33707d6)
gg(c,d,a,b,m3,14,0xf4d50d87)
gg(b,c,d,a,m8,20,0x455a14ed)
gg(a,b,c,d,m13,5,0xa9e3e905)
gg(d,a,b,c,m2,9,0xfcefa3f8)
gg(c,d,a,b,m7,14,0x676f02d9)
gg(b,c,d,a,m12,20,0x8d2a4c8a)
第三輪
hh(a,b,c,d,m5,4,0xfffa3942)
hh(d,a,b,c,m8,11,0x8771f681)
hh(c,d,a,b,m11,16,0x6d9d6122)
hh(b,c,d,a,m14,23,0xfde5380c)
hh(a,b,c,d,m1,4,0xa4beea44)
hh(d,a,b,c,m4,11,0x4bdecfa9)
hh(c,d,a,b,m7,16,0xf6bb4b60)
hh(b,c,d,a,m10,23,0xbebfbc70)
hh(a,b,c,d,m13,4,0x289b7ec6)
hh(d,a,b,c,m0,11,0xeaa127fa)
hh(c,d,a,b,m3,16,0xd4ef3085)
hh(b,c,d,a,m6,23,0x04881d05)
hh(a,b,c,d,m9,4,0xd9d4d039)
hh(d,a,b,c,m12,11,0xe6db99e5)
hh(c,d,a,b,m15,16,0x1fa27cf8)
hh(b,c,d,a,m2,23,0xc4ac5665)
第四輪
ii(a,b,c,d,m0,6,0xf4292244)
ii(d,a,b,c,m7,10,0x432aff97)
ii(c,d,a,b,m14,15,0xab9423a7)
ii(b,c,d,a,m5,21,0xfc93a039)
ii(a,b,c,d,m12,6,0x655b59c3)
ii(d,a,b,c,m3,10,0x8f0ccc92)
ii(c,d,a,b,m10,15,0xffeff47d)
ii(b,c,d,a,m1,21,0x85845dd1)
ii(a,b,c,d,m8,6,0x6fa87e4f)
ii(d,a,b,c,m15,10,0xfe2ce6e0)
ii(c,d,a,b,m6,15,0xa3014314)
ii(b,c,d,a,m13,21,0x4e0811a1)
ii(a,b,c,d,m4,6,0xf7537e82)
ii(d,a,b,c,m11,10,0xbd3af235)
ii(c,d,a,b,m2,15,0x2ad7d2bb)
ii(b,c,d,a,m9,21,0xeb86d391)
常數ti可以如下選擇:
在第i步中,ti是4294967296*abs(sin(i))的整數部分,i的單位是弧度。(4294967296等於2的32次方)
所有這些完成之後,將a、b、c、d分別加上a、b、c、d。然後用下一分組數據繼續運行演算法,最後的輸出是a、b、c和d的級聯。
當你按照我上面所說的方法實現md5演算法以後,你可以用以下幾個信息對你做出來的程序作一個簡單的測試,看看程序有沒有錯誤。
md5 ("") =
md5 ("a") =
md5 ("abc") =
md5 ("message digest") =
md5 ("abcdefghijklmnopqrstuvwxyz") =
md5 ("") =
md5 ("1234567890") =
如果你用上面的信息分別對你做的md5演算法實例做測試,最後得出的結論和標准答案完全一樣,那我就要在這里象你道一聲祝賀了。要知道,我的程序在第一次編譯成功的時候是沒有得出和上面相同的結果的。
四、MD5的安全性
md5相對md4所作的改進:
1. 增加了第四輪;
2. 每一步均有唯一的加法常數;
3. 為減弱第二輪中函數g的對稱性從(x&y)|(x&z)|(y&z)變為(x&z)|(y&(~z));
4. 第一步加上了上一步的結果,這將引起更快的雪崩效應;
5. 改變了第二輪和第三輪中訪問消息子分組的次序,使其更不相似;
6. 近似優化了每一輪中的循環左移位移量以實現更快的雪崩效應。各輪的位移量互不相同。
㈡ java.awt的類摘要
AlphaComposite AlphaComposite 類實現一些基本的 alpha 合成規則,將源色與目標色組合,在圖形和圖像中實現混合和透明效果。 AWTEvent 所有 AWT 事件的根事件類。 AWTEventMulticaster AWTEventMulticaster 實現對 java.awt.event 包中定義的 AWT 事件的指派,該指派是有效的、線程安全的多路廣播事件指派。 AWTKeyStroke AWTKeyStroke 表示鍵盤(或等效輸入設備)上的鍵操作。 AWTPermission 此類用於 AWT 許可權。 BasicStroke BasicStroke 類定義針對圖形圖元輪廓呈現屬性的一個基本集合,這些圖元使用Graphics2D對象呈現,而該對象的 Stroke 屬性設置為此 BasicStroke。 BorderLayout 這是一個布置容器的邊框布局,它可以對容器組件進行安排,並調整其大小,使其符合下列五個區域:北、南、東、西、中。 BufferCapabilities 緩沖區的能力和屬性。 BufferCapabilities.FlipContents 頁面翻轉後可能的後台緩沖區內容的一個類型安全的枚舉 Button 此類創建一個標簽按鈕。 Canvas Canvas 組件表示屏幕上一個空白矩形區域,應用程序可以在該區域內繪圖,或者可以從該區域捕獲用戶的輸入事件。 CardLayout CardLayout 對象是容器的布局管理器。 Checkbox 復選框是一個可處於「開」(true) 或「關」(false) 狀態的圖形組件。 CheckboxGroup CheckboxGroup 類用於集合 Checkbox 按鈕集。 CheckboxMenuItem 此類表示一個可包括在菜單中的復選框。 Choice Choice 類表示一個彈出式選擇菜單。 Color Color 類用於封裝默認 sRGB 顏色空間中的顏色,或者用於封裝由ColorSpace標識的任意顏色空間中的顏色。 Component component是一個具有圖形表示能力的對象,可在屏幕上顯示,並可與用戶進行交互。 ComponentOrientation ComponentOrientation 類封裝語言敏感的方向,用於排序組件或文本內容。 Container 一般的 Abstract Window Toolkit(AWT) 容器對象是一個可包含其他 AWT 組件的組件。 Cursor 封裝滑鼠游標的點陣圖表示形式的類。 DefaultKeyboardFocusManager AWT 應用程序的默認 KeyboardFocusManager。 Desktop Desktop 類允許 Java 應用程序啟動已在本機桌面上注冊的關聯應用程序,以處理URI或文件。 Dialog Dialog 是一個帶標題和邊界的頂層窗口,邊界一般用於從用戶處獲得某種形式的輸入。 Dimension Dimension 類封裝單個對象中組件的寬度和高度(精確到整數)。 DisplayMode DisplayMode 類封裝 GraphicsDevice 的位深、高度、寬度和刷新率。 Event 註:Event 類已廢棄,只可用於向後兼容。 EventQueue EventQueue 是一個與平台無關的類,它將來自於底層同位體類和受信任的應用程序類的事件列入隊列。 FileDialog FileDialog 類顯示一個對話框窗口,用戶可以從中選擇文件。 FlowLayout 流布局用於安排有向流中的組件,這非常類似於段落中的文本行。 FocusTraversalPolicy FocusTraversalPolicy 定義一種順序,按此順序遍歷具有特定焦點循環根的 Component。 Font Font 類表示字體,可以使用它以可見方式呈現文本。 FontMetrics FontMetrics 類定義字體規格對象,該對象封裝將在特定屏幕上呈現特定字體的有關信息。 Frame Frame 是帶有標題和邊框的頂層窗口。 GradientPaint GradientPaint 類提供了使用線性顏色漸變模式填充Shape的方法。 Graphics Graphics 類是所有圖形上下文的抽象基類,允許應用程序在組件(已經在各種設備上實現)以及閉屏圖像上進行繪制。 Graphics2D 此 Graphics2D 類擴展Graphics類,以提供對幾何形狀、坐標轉換、顏色管理和文本布局更為復雜的控制。 GraphicsConfigTemplate GraphicsConfigTemplate 類用於獲得有效的GraphicsConfiguration。 GraphicsConfiguration GraphicsConfiguration 類描述圖形目標(如列印機或監視器)的特徵。 GraphicsDevice GraphicsDevice 類描述可以在特定圖形環境中使用的圖形設備。 GraphicsEnvironment GraphicsEnvironment 類描述了 Java(tm) 應用程序在特定平台上可用的GraphicsDevice對象和Font對象的集合。 GridBagConstraints GridBagConstraints 類指定使用 GridBagLayout 類布置的組件的約束。 GridBagLayout GridBagLayout 類是一個靈活的布局管理器,它不要求組件的大小相同便可以將組件垂直、水平或沿它們的基線對齊。 GridBagLayoutInfo GridBagLayoutInfo 是 GridBagLayout 布局管理器的一個實用工具類。 GridLayout GridLayout 類是一個布局處理器,它以矩形網格形式對容器的組件進行布置。 Image 抽象類 Image 是表示圖形圖像的所有類的超類。 ImageCapabilities 圖像的功能和屬性。 Insets Insets 對象是容器邊界的表示形式。 JobAttributes 控制列印作業的屬性集合。 JobAttributes.DefaultSelectionType 可能的默認選擇狀態的類型安全的枚舉。 JobAttributes.DestinationType 可能的作業目標的類型安全枚舉。 JobAttributes.DialogType 顯示給用戶的可能對話框的類型安全枚舉。 JobAttributes.MultipleDocumentHandlingType 可能的多副本處理狀態的類型安全枚舉。 JobAttributes.SidesType 可能的多頁整版的類型安全枚舉。 KeyboardFocusManager KeyboardFocusManager 負責管理激活狀態的聚焦 Window 和當前焦點所有者。 Label Label 對象是一個可在容器中放置文本的組件。 LinearGradientPaint LinearGradientPaint 類提供利用線性顏色漸變模式填充Shape的方式。 List List 組件為用戶提供了一個可滾動的文本項列表。 MediaTracker MediaTracker 類是一個跟蹤多種媒體對象狀態的實用工具類。 Menu Menu 對象是從菜單欄部署的下拉式菜單組件。 MenuBar MenuBar 類封裝綁定到框架的菜單欄的平台概念。 MenuComponent 抽象類 MenuComponent 是所有與菜單相關的組件的超類。 MenuItem 菜單中的所有項必須屬於類 MenuItem 或其子類之一。 MenuShortcut 表示 MenuItem 鍵盤加速器的 MenuShortcut 類。 MouseInfo MouseInfo 提供獲取有關滑鼠信息的方法,如滑鼠指針位置和滑鼠按鈕數。 MultipleGradientPaint 這是 Paints 的超類,它使用多個顏色漸變來填充它們的光柵。 PageAttributes 用來控制列印頁面輸出的屬性集。 PageAttributes.ColorType 可能顏色狀態的類型安全的枚舉。 PageAttributes.MediaType 可能的紙張大小的類型安全的枚舉。 PageAttributes.OrientationRequestedType 可能列印方向的類型安全的枚舉。 PageAttributes.OriginType 可能原點的類型安全的枚舉。 PageAttributes.PrintQualityType 可能的列印質量的類型安全的枚舉。 Panel Panel 是最簡單的容器類。 Point 表示 (x,y) 坐標空間中的位置的點,以整數精度指定。 PointerInfo 描述指針位置的類。 Polygon Polygon 類封裝了坐標空間中封閉的二維區域的描述。 PopupMenu 此類實現能夠在組件中的指定位置上動態彈出的菜單。 PrintJob 啟動並執行列印作業的抽象類。 RadialGradientPaint RadialGradientPaint 類提供使用圓形輻射顏色漸變模式填充某一形狀的方式。 Rectangle Rectangle 指定坐標空間中的一個區域,通過坐標空間中 Rectangle 對象左上方的點 (x,y)、寬度和高度可以定義這個區域。 RenderingHints RenderingHints 類定義和管理鍵和關聯值的集合,它允許應用程序將輸入提供給其他類使用的演算法選擇,這些類執行呈現和圖像處理服務。 RenderingHints.Key 定義與RenderingHints一起使用的、用來控制呈現和圖像管線中各種演算法選擇的所有鍵的基本類型。 Robot 此類用於為測試自動化、自運行演示程序和其他需要控制滑鼠和鍵盤的應用程序生成本機系統輸入事件。 Scrollbar Scrollbar 類描述了一個滾動條,這是大家都很熟悉的用戶界面對象。 ScrollPane 實現用於單個子組件的自動水平和/或垂直滾動的容器類。 ScrollPaneAdjustable 此類表示 ScrollPane 的水平或垂直滾動條的狀態。 SplashScreen 在 Java 虛擬機 (JVM) 啟動之前,可以在應用程序啟動時創建閃現屏幕。 SystemColor 封裝表示系統中本機 GUI 對象顏色的象徵性顏色的類。 SystemTray SystemTray 類表示桌面的系統托盤。 TextArea TextArea 對象是顯示文本的多行區域。 TextComponent TextComponent 類是所有允許編輯文本的組件的超類。 TextField TextField 對象是允許編輯單行文本的文本組件。 TexturePaint TexturePaint 類提供一種用被指定為BufferedImage的紋理填充Shape的方式。 Toolkit 此類是所有 Abstract Window Toolkit 實際實現的抽象超類。 TrayIcon TrayIcon 對象表示可以添加到系統托盤的托盤圖標。 Window Window 對象是一個沒有邊界和菜單欄的頂層窗口。
㈢ springboot添加依賴(springboot添加依賴報錯)
SpringBootWeb項目依賴分析在上篇中,我們得到如下的pom.xml
看看其核心類容:
按住ctrl並點擊parent中spring-boot-stater-parent節點,可以看到
spring-boot-stater-parent有一個parentspring-boot-dependencies
根據名字分析,是spring-boot項目依賴的
繼續點擊spring-boot-dependencies
可以看到其在properties中配置了大量的依賴版本
我當前這個版本(2.2.3.RELEASE)在properties中共配置了203個依賴的版本
properties下面dependencyManagement節點中,配置了依賴組建的版本:
在項目的pom.xml中查看依賴樹:
可以看到springboot-starter-web添加了tomcat,web,webmvc,spring-core,spring-context等依賴
這也就是為什麼我們可以直接通過DemoApplication.main來運行,而不需要配置外部servlet容器的原因,同時,通過這個starter-web就已經將web相關的依賴都整合進來了。
springboot中提供了很多starter,比如
springBoot必用依賴框架使用Lombok框架
在編寫POJO類型(包括實體類、VO、DTO等)時,都有統一的編碼規范,例如:
由於以上操作方式非常固定,且涉及的代碼量雖然不難,但是篇幅較長,並且,當類中的屬性需要修改時(包括修改原有屬性、或增加新屬性、刪除原有屬性),對應的其它方法都需要修改(或重新生成),管理起來比較麻煩。
在SpringBoot中,添加Lombok依賴,可以在創建項目時勾選,也可以後期自行添加,依賴項的代碼為:
完成後,在各POJO類型中,將不再需要在源代碼添加SettersGetters、`equals()`、`hashCode()`、`toString()`這些方法,只需要在POJO類上添加`@Data`註解即可!
當添加`@Data`註解,且刪除相關方法後,由於源代碼中沒有相關方法,則調用了相關代碼的方法可能會報錯,但是,並不影響程序運行!
為了避免IntelliJIDEA判斷失誤而提示了警告和錯誤,推薦安裝Lombok插件,可參考:
【注】:無論是否安裝插件,都不影響代碼的編寫和運行!
Slf4j日誌框架
在開發實踐中,不允許使用`System.out.println()`或類似的輸出語句來輸出顯示關鍵數據(核心數據、敏感數據等),因為,如果是這樣使用,無論是在開發環境,還是測試環境,還是生產環境中,這些輸出語句都將輸出相關信息,而刪除或添加這些輸出語句的操作成本比較高,操作可行性低。
推薦的做法是使用日誌框架來輸出相關信息!
在Slf4j日誌框架中,將日誌的可顯示級別根據其重要程度(嚴重程度)由低到高分為:
在配置文件中,可以通過`logging.level.包名.類名`來設置當前類的日誌顯示級別,例如:
當設置了顯示的日誌級別後,僅顯示設置級別和更重要的級別的日誌,例如,設置為`info`時,只顯示`info`、`warn`、`error`,不會顯示`debug`、`trace`級別的日誌!
當輸出日誌時,通過`log`變數調用`trace()`方法輸出的日誌就是`trace`級別的,調用`debug()`方法輸出的日誌就是`debug()`級別的,以此類推,可調用的方法還有`info()`、`warn()`、`error()`。
在開發實踐中,關鍵數據和敏感數據都應該通過`trace()`或`debug()`進行輸出,在開發環境中,可以將日誌的顯示級別設置為`trace`,則會顯示所有日誌,當需要交付到生產環境中時,只需要將日誌的顯示級別調整為`info`即可!
默認情況下,日誌的顯示級別是`info`,所以,即使沒有在配置文件中進行正確的配置,所有info、warn、error級別的日誌都會輸出顯示。
在使用Slf4j時,通過`log`調用的每種級別的方法都被重載了多次(各級別對應除了方法名稱不同,重載的次數和參數列表均相同),推薦使用的方法是參數列表為`(Stringformat,Object...arguments)`的,例如:
以上方法中,第1個參數是將要輸出的字元串的模式(模版),在此字元串中,如果需要包含某個變數值,則使用`{}`表示,如果有多個變數值,均是如此,然後,再通過第2個參數(是可變參數)依次表示各`{}`對應的值,例如:
使用這種做法,可以避免多變數時頻繁的拼接字元串,另外,日誌框架會將第1個參數進行緩存,以此提高後續每一次的執行效率。
在開發實踐中,應該對程序執行關鍵位置添加日誌的輸出,通常包括:
其實,Slf4j日誌框架只是日誌的一種標准,並不是具體的實現(感覺上與Java中的介面有點相似),常見有具體實現了日誌功能的框架有log4j、logback等,為了統一標准,所以才出現了Slf4j,同時,由於log4j、logback等框架實現功能並不統一,所以,Slf4j提供了對主流日誌框架的兼容,在SpringBoot工程中,`spring-boot-starter`就已經依賴了`spring-boot-starter-logging`,而在此依賴下,通常包括Slf4j、具體的日誌框架、Slf4j對具體日誌框架的兼容。
密碼加密(額外知識點)
【這並不是SpringBoot框架的知識點】
對密碼進行加密,可以有效的保障密碼安全,即使出現資料庫泄密,密碼安全也不會受到影響!為了實現此目標,需要在對密碼進行加密時,使用不可逆的演算法進行處理!
通常,不可以使用加密演算法對密碼進行加密碼處理,從嚴格定義上來看,所有的加密演算法都是可以逆向運算的,即同時存在加密和解密這2種操作,加密演算法只能用於保證傳輸過程的安全,並不應該用於保證需要存儲下來的密碼的安全!
哈希演算法都是不可逆的,通常,用於處理密碼加密的演算法中,典型的是一些消息摘要演算法,例如MD5、SHA256或以上位數的演算法。
消息摘要演算法的主要特徵有:
在消息摘要演算法中,以MD5為例,其運算結果是一個128位長度的二進制數,通常會轉換成十六進制數顯示,所以是32位長度的十六進制數,MD5也被稱之為128位演算法。理論上,會存在2的128次方種類的摘要結果,且對應2的128次方種不同的消息,如果在未超過2的128次方種消息中,存在2個或多個不同的消息對應了相同的摘要,則稱之為:發生了碰撞。一個消息摘要演算法是否安全,取決其實際的碰撞概率,關於消息摘要演算法的破解,也是研究其碰撞概率。
存在窮舉消息和摘要的對應關系,並利用摘要在此對應關系進行查詢,從而得知消息的做法,但是,由於MD5是128位演算法,全部窮舉是不可能實現的,所以,只要原始密碼(消息)足夠復雜,就不會被收錄到所記錄的對應關系中去!
為了進一步提高密碼的安全性,在使用消息摘要演算法進行處理時,通常還會加鹽!鹽值可以是任意的字元串,用於與密碼一起作為被消息摘要演算法運算的數據即可,例如:
加鹽的目的是使得被運算數據變得更加復雜,鹽值本身和用法並沒有明確要求!
甚至,在某些用法或演算法中,還會使用隨機的鹽值,則可以使用完全相同的原消息對應的摘要卻不同!
推薦了解:預計算的哈希鏈、彩虹表、雪花演算法。
為了進一步保證密碼安全,還可以使用多重加密,即反復調用消息摘要演算法。
除此以外,還可以使用安全系數更高的演算法,例如SHA-256是256位演算法,SHA-384是384位演算法,SHA-512是512位演算法。
Validation框架
當客戶端向伺服器提交請求時,如果請求數據出現明顯的問題(例如關鍵數據為`null`、字元串的長度不在可接受范圍內、其它格式錯誤),應該直接響應錯誤,而不是將明顯錯誤的請求參數傳遞到Service!
關於判斷錯誤,只有涉及資料庫中的數據才能判斷出結果的,都由Service進行判斷,而基本的格式判斷,都由Controller進行判斷。
Validation框架是專門用於解決檢查數據基本格式有效性的,最早並不是Spring系列的框架,目前,SpringBoot提供了更好的支持,所以,通常結合在一起使用。
在SpringBoot項目中,需要添加`spring-boot-starter-validation`依賴項,例如:
在控制器中,首先,對需要檢查數據格式的請求參數添加`@Valid`或`@Validated`註解(這2個註解沒有區別),例如:
真正需要檢查的是`AdminAddNewDTO`中各屬性的值,所以,接下來需要在此類的各屬性上通過註解來配置檢查的規則,例如:
重啟項目,通過不提交用戶名的URL(例如:)進行訪問,在瀏覽器上會出現400錯誤頁面,並且,在IntelliJIDEA的控制台會出現以下警告:
從警告信息中可以看到,當驗證失敗時(不符合所使用的註解對應的規則時),會出現`org.springframework.validation.BindException`異常,則自行處理此異常即可!
首先,在`State`中添加新的枚舉:
然後,在`GlobalExceptionHandler`中添加新的處理異常的方法:
關於錯誤提示信息,以上內容中出現了`不能為null`的字樣,是默認的提示文本,可以通過`@NotNull`註解的`message`屬性進行配置,例如:
然後,在處理異常時,通過異常信息獲取自定義的提示文本:
再次運行,在不提交用戶名和密碼的情況下,會隨機的提示用戶名或密碼驗證失敗的提示文本中的某1條。
在Validation框架中,還有其它許多註解,用於進行不同格式的驗證,例如:
以上註解,包括`@NotNull`是允許疊加使用的,即允許在同一個參數屬性上添加多個註解!
以上註解均可以配置`message`屬性,用於指定驗證失敗的提示文本。
通常:(開發中)
Springboot動態的配置Scheling一:springboot配置靜態定時任務
1:pom中添加依賴
2:啟動類中加入@EnableScheling來開啟定時任務
3:@Scheled(cron=?"0/10****?")//每過10秒執行一次
二:?springboot動態配置定時任務:主要動態的配置。
packagecom.example.demo.config;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.lang.Nullable;
importorg.springframework.scheling.Trigger;
importorg.springframework.scheling.TriggerContext;
importorg.springframework.scheling.concurrent.ThreadPoolTaskScheler;
importorg.springframework.scheling.support.CronTrigger;
importorg.springframework.stereotype.Component;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.concurrent.ScheledFuture;
@Component
@Configuration
{
@Autowired
??;
??@Bean
??(){
();
??}
privateScheledFuturefuture;
??privateStringcron="";
??publicStringgetCron(){
returncron;
??}
publicvoidsetCron(Stringcron){
this.cron=cron;
????stopCron();
????future=threadPoolTaskScheler.schele(newRunnable(){
@Override
???????publicvoidrun(){
try{
System.out.println(newSimpleDateFormat("yyyy-MM-ddHH:mm:ss").format(newDate()));
?????????}catch(Exceptione){
e.printStackTrace();
?????????}
}
},newTrigger(){
@Nullable
@Override
???????publicDatenextExecutionTime(TriggerContexttriggerContext){
if("".equals(cron)||cron==null){
returnnull;
?????????}
CronTriggercronTrigger=newCronTrigger(cron);
?????????DatenextExeDate=cronTrigger.nextExecutionTime(triggerContext);
?????????returnnextExeDate;
???????}
});
??}
publicvoidstopCron(){
if(future!=null){
future.cancel(true);
????}
}
}
關於springboot如何添加其他依賴spring?boot?基本依賴
1.基礎核心依賴
parent
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-parent/artifactId????version1.5.1.RELEASE/version
/parent
2.web應用依賴
dependencies
dependency
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-web/artifactId
/dependency
/dependencies
3.使用freemark依賴(不和web應用依賴共存)
dependencies
dependency
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-freemarker/artifactId
/dependency
/dependencies
擴充一下:
㈣ 開發中常見的加密方式及應用
開發中常見的加密方式及應用
一、base64
簡述:Base64是網路上最常見的用於傳輸8Bit 位元組碼 的編碼方式之一,Base64就是一種基於64個可列印字元來表示二進制數據的方法。所有的數據都能被編碼為並只用65個字元就能表示的文本文件。( 65字元:A~Z a~z 0~9 + / = )編碼後的數據~=編碼前數據的4/3,會大1/3左右(圖片轉化為base64格式會比原圖大一些)。
應用:Base64編碼是從二進制到字元的過程,可用於在 HTTP 環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base64來將一個較長的唯一 標識符 (一般為128-bit的UUID)編碼為一個字元串,用作HTTP 表單 和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制 數據編碼 為適合放在URL(包括隱藏 表單域 )中的形式。此時,採用Base64編碼具有不可讀性,需要解碼後才能閱讀。
命令行進行Base64編碼和解碼
編碼:base64 123.png -o 123.txt
解碼:base64 123.txt -o test.png -D Base64編碼的原理
原理:
1)將所有字元轉化為ASCII碼;
2)將ASCII碼轉化為8位二進制;
3)將二進制3個歸成一組(不足3個在後邊補0)共24位,再拆分成4組,每組6位;
4)統一在6位二進制前補兩個0湊足8位;
5)將補0後的二進制轉為十進制;
6)從Base64編碼表獲取十進制對應的Base64編碼;
Base64編碼的說明:
a.轉換的時候,將三個byte的數據,先後放入一個24bit的緩沖區中,先來的byte占高位。
b.數據不足3byte的話,於緩沖區中剩下的bit用0補足。然後,每次取出6個bit,按照其值選擇查表選擇對應的字元作為編碼後的輸出。
c.不斷進行,直到全部輸入數據轉換完成。
d.如果最後剩下兩個輸入數據,在編碼結果後加1個「=」;
e.如果最後剩下一個輸入數據,編碼結果後加2個「=」;
f.如果沒有剩下任何數據,就什麼都不要加,這樣才可以保證資料還原的正確性。
二、HASH加密/單向散列函數
簡述:Hash演算法特別的地方在於它是一種單向演算法,用戶可以通過Hash演算法對目標信息生成一段特定長度(32個字元)的唯一的Hash值,卻不能通過這個Hash值重新獲得目標信息。對用相同數據,加密之後的密文相同。 常見的Hash演算法有MD5和SHA。由於加密結果固定,所以基本上原始的哈希加密已經不再安全,於是衍生出了加鹽的方式。加鹽:先對原始數據拼接固定的字元串再進行MD5加密。
特點:
1) 加密 後密文的長度是定長(32個字元的密文)的
2)如果明文不一樣,那麼散列後的結果一定不一樣
3)如果明文一樣,那麼加密後的密文一定一樣(對相同數據加密,加密後的密文一樣)
4)所有的加密演算法是公開的
5)不可以逆推反算(不能根據密文推算出明文),但是可以暴力 破解 ,碰撞監測
原理:MD5消息摘要演算法,屬Hash演算法一類。MD5演算法對輸入任意長度的消息進行運行,產生一個128位的消息摘要。
1)數據填充
對消息進行數據填充,使消息的長度對512取模得448,設消息長度為X,即滿足X mod 512=448。根據此公式得出需要填充的數據長度。
填充方法:在消息後面進行填充,填充第一位為1,其餘為0。
2)添加信息長度
在第一步結果之後再填充上原消息的長度,可用來進行的存儲長度為64位。如果消息長度大於264,則只使用其低64位的值,即(消息長度 對264取模)。
在此步驟進行完畢後,最終消息長度就是512的整數倍。
3)數據處理
准備需要用到的數據:
4個常數:A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;
4個函數:F(X,Y,Z)=(X & Y) | ((~X) & Z);G(X,Y,Z)=(X & Z) | (Y & (~Z));H(X,Y,Z)=X ^ Y ^ Z;I(X,Y,Z)=Y ^ (X | (~Z));
把消息分以512位為一分組進行處理,每一個分組進行4輪變換,以上面所說4個常數為起始變數進行計算,重新輸出4個變數,以這4個變數再進行下一分組的運算,如果已經是最後一個分組,則這4個變數為最後的結果,即MD5值。
三、對稱加密
經典演算法:
1)DES數據加密標准
DES演算法的入口參數有三個:Key、Data、Mode。其中Key為8個位元組共64位,是DES演算法的工作密鑰;Data也為8個位元組64位,是要被加密或被解密的數據;Mode為DES的工作方式,有兩種:加密或解密。
DES演算法是這樣工作的:如Mode為加密,則用Key去把數據Data進行加密, 生成Data的密碼形式(64位)作為DES的輸出結果;如Mode為解密,則用Key去把密碼形式的數據Data解密,還原為Data的明碼形式(64位)作為DES的輸出結果。在通信網路的兩端,雙方約定一致的Key,在通信的源點用Key對核心數據進行DES加密,然後以密碼形式在公共通信網(如電話網)中傳輸到通信網路的終點,數據到達目的地後,用同樣的Key對密碼數據進行解密,便再現了明碼形式的核心數據。這樣,便保證了核心數據(如PIN、MAC等)在公共通信網中傳輸的安全性和可靠性。
2)3DES使用3個密鑰,對消息進行(密鑰1·加密)+(密鑰2·解密)+(密鑰3·加密)
3)AES高級加密標准
如圖,加密/解密使用相同的密碼,並且是可逆的
四、非對稱加密
特點:
1)使用公鑰加密,使用私鑰解密
2)公鑰是公開的,私鑰保密
3)加密處理安全,但是性能極差
經典演算法RSA:
1)RSA原理
(1)求N,准備兩個質數p和q,N = p x q
(2)求L,L是p-1和q-1的最小公倍數。L = lcm(p-1,q-1)
(3)求E,E和L的最大公約數為1(E和L互質)
(4)求D,E x D mode L = 1
五、數字簽名
原理以及應用場景:
1)數字簽名的應用場景
需要嚴格驗證發送方身份信息情況
2)數字簽名原理
(1)客戶端處理
對"消息"進行HASH得到"消息摘要"
發送方使用自己的私鑰對"消息摘要"加密(數字簽名)
把數字簽名附著在"報文"的末尾一起發送給接收方
(2)服務端處理
對"消息" HASH得到"報文摘要"
使用公鑰對"數字簽名"解密
對結果進行匹配
六、數字證書
簡單說明:
證書和駕照很相似,裡面記有姓名、組織、地址等個人信息,以及屬於此人的公鑰,並有認證機構施加數字簽名,只要看到公鑰證書,我們就可以知道認證機構認證該公鑰的確屬於此人。
數字證書的內容:
1)公鑰
2)認證機構的數字簽名
證書的生成步驟:
1)生成私鑰openssl genrsa -out private.pem 1024
2)創建證書請求openssl req -new -key private.pem -out rsacert.csr
3)生成證書並簽名,有效期10年openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
4)將PEM格式文件轉換成DER格式openssl x509 -outform der -in rsacert.crt -out rsacert.der
5)導出P12文件openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt
iOS開發中的注意點:
1)在iOS開發中,不能直接使用PEM格式的證書,因為其內部進行了Base64編碼,應該使用的是DER的證書,是二進制格式的;
2)OpenSSL默認生成的都是PEM格式的證書。
七、https
HTTPS和HTTP的區別:
超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站伺服器之間傳遞信息。HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站伺服器之間的傳輸報文,就可以直接讀懂其中的信息,因此HTTP協議不適合傳輸一些敏感信息,比如信用卡號、密碼等。
為了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS。為了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證伺服器的身份,並為瀏覽器和伺服器之間的通信加密。
HTTPS和HTTP的區別主要為以下四點:
1)https協議需要到ca申請證書,一般免費證書很少,需要交費。
2)http是 超文本傳輸協議 ,信息是明文傳輸,https則是具有 安全性 的 ssl 加密傳輸協議。
3)http和https使用的是完全不同的連接方式,用的埠也不一樣,前者是80,後者是443。
4)http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的 網路協議 ,比http協議安全。
5)SSL:Secure Sockets Layer安全套接字層;用數據加密(Encryption)技術,可確保數據在網路上傳輸過程中不會被截取及竊聽。目前一般通用之規格為40 bit之安全標准,美國則已推出128 bit之更高安全標准,但限制出境。只要3.0版本以上之I.E.或Netscape 瀏覽器 即可支持SSL。目前版本為3.0。SSL協議位於TCP/IP協議與各種應用層協議之間,為數據通訊提供安全支持。SSL協議可分為兩層:SSL記錄協議(SSL Record Protocol):它建立在可靠的傳輸協議(如TCP)之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持。SSL握手協議(SSL Handshake Protocol):它建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密演算法、交換加密密鑰等。