Java中的MessageDigest類加密詳解
MessageDigest類
MessageDigest 類是一個引擎類,它是為了提供諸如 SHA1 或 MD5 等密碼上安全的報文摘要功能而設(shè)計的。
密碼上安全的報文摘要可接受任意大小的輸入(一個字節(jié)數(shù)組),并產(chǎn)生固定大小的輸出,該輸出稱為一個摘要或散列。
創(chuàng)建MessageDigest對象
計算信息摘(即散列碼)要做的第一步是創(chuàng)建 MessageDigest對象 實例。
像所有的引擎類一樣,獲取某類報文摘要算法(即散列算法,比如MD5)的 MessageDigest 對象的途徑是調(diào)用 MessageDigest 類中的 getInstance 靜態(tài) factory 方法:
public static MessageDigest getInstance(String algorithm)
- 注意1:即時給定MessageDigest的實現(xiàn)是不可復(fù)制的,則仍然能夠通過getInstance方法實例化幾個實例計算來同時進行摘要信息的計算。
- 注意2:由于歷史原因,此類是抽象的,是從 MessageDigestSpi 擴展的。應(yīng)用程序開發(fā)人員只應(yīng)該注意在此 MessageDigest 類中定義的方法;超類中的所有方法是供希望提供自己的信息摘要算法實現(xiàn)的加密服務(wù)提供者使用的。
- 注意3:MessageDigest并不是單實例的。如下代碼所示:
try { MessageDigest mdTemp1 = MessageDigest.getInstance("MD5"); MessageDigest mdTemp2= MessageDigest.getInstance("MD5"); MessageDigest mdTemp3= MessageDigest.getInstance("MD5"); System.out.println("mdTemp1==mdTemp2?:"+(mdTemp1==mdTemp2)); System.out.println("mdTemp2==mdTemp3?:"+(mdTemp2==mdTemp3)); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); }
運行結(jié)果
mdTemp1==mdTemp2?:false
mdTemp2==mdTemp3?:false
注意:算法名不區(qū)分大小寫。例如,以下所有調(diào)用都是相等的:
MessageDigest.getInstance("SHA"); MessageDigest.getInstance("sha"); MessageDigest.getInstance("sHa");
方法摘要
方法 | 摘要 |
Object | clone() 如果實現(xiàn)是可復(fù)制的,則返回一個副本。 |
byte[] | digest() 通過執(zhí)行諸如填充之類的最終操作完成哈希計算。 |
byte[] | digest(byte[] input) 使用指定的字節(jié)數(shù)組對摘要進行最后更新,然后完成摘要計算。 |
int | digest(byte[] buf, int offset, int len) 通過執(zhí)行諸如填充之類的最終操作完成哈希計算。 |
String | getAlgorithm() 返回標識算法的獨立于實現(xiàn)細節(jié)的字符串。 |
int | getDigestLength() 返回以字節(jié)為單位的摘要長度,如果提供程序不支持此操作并且實現(xiàn)是不可復(fù)制的,則返回 0。 |
static MessageDigest | getInstance(String algorithm) 生成實現(xiàn)指定摘要算法的 MessageDigest 對象。 |
static MessageDigest | getInstance(String algorithm, Provider provider) 生成實現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。 |
static MessageDigest | getInstance(String algorithm, String provider) 生成實現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。 |
Provider | getProvider() 返回此信息摘要對象的提供程序。 |
static boolean | isEqual(byte[] digesta, byte[] digestb) 比較兩個摘要的相等性。 |
void | reset() 重置摘要以供再次使用。 |
String | toString() 返回此信息摘要對象的字符串表示形式。 |
void | update(byte input) 使用指定的字節(jié)更新摘要。 |
void | update(byte[] input) 使用指定的字節(jié)數(shù)組更新摘要。 |
void | update(byte[] input, int offset, int len) 使用指定的字節(jié)數(shù)組,從指定的偏移量開始更新摘要。 |
void | update(ByteBuffer input) 使用指定的 ByteBuffer 更新摘要。 |
例子演示
public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest instance = MessageDigest.getInstance("md5"); String UUID = java.util.UUID.randomUUID().toString(); String pwd = "123456"; String name = UUID+pwd; System.out.println("鹽值:"+UUID); System.out.println("密碼:"+pwd); System.out.println("鹽值加密:"+name); instance.update(name.getBytes()); instance.reset(); byte[] digest = instance.digest(name.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : digest) { String row = Integer.toHexString(b&0xff); if(row.length()==1){ row = "0" + row; } sb.append(row); } System.out.println("加密后:"+sb.toString()); }
文件摘要加密
public void insertAttachement(String title, MultipartFile mFile) { if(title==null||title.trim().length()==0){ throw new ServiceException("標題不能為空"); } if(mFile==null){ throw new ServiceException("不允許上傳空文件"); } byte[] bytes ; String digests= null; try { //將文件摘要轉(zhuǎn)為字節(jié) bytes = mFile.getBytes(); //將摘要后的字節(jié)數(shù)組進行MD5加密 digests = DigestUtils.md5DigestAsHex(bytes); } catch (Exception e) { e.printStackTrace(); throw new ServiceException("文件上傳失敗"); } Integer rows = attachementsDao.getRowCountByDigest(digests); if(rows>0){ throw new ServiceException("文件已上傳,請勿重復(fù)上傳!"); } String fileName = mFile.getOriginalFilename(); String contentType = mFile.getContentType(); SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); String timeDate = sd.format(new Date()); String path = "F:"+File.separator+"upload"+File.separator+timeDate; File file = new File(path); //文件夾是否存在 不存在將創(chuàng)建 if(!file.exists()){ file.mkdirs(); } File filepath = new File(path,fileName); try { mFile.transferTo(filepath); } catch (IOException e) { e.printStackTrace(); throw new ServiceException("文件上傳失敗"); } Attachements att = new Attachements(); att.setTitle(title); att.setFileName(fileName); att.setFilePath(filepath.getAbsolutePath()); att.setFileDisgest(digests); att.setContentType(contentType); Integer row = attachementsDao.insertAttachement(att); if(row<1){ throw new ServiceException("新增失敗"); } }
運行結(jié)果
鹽值:c971db77-f109-401a-95f7-49b0f2bf0863
密碼:123456
鹽值加密:c971db77-f109-401a-95f7-49b0f2bf0863123456
加密后:525f7296b1ca744ca751344a4196ad17
到此這篇關(guān)于Java中的MessageDigest類加密詳解的文章就介紹到這了,更多相關(guān)MessageDigest類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot2.x結(jié)合Mabatis3.x下Hikari連接數(shù)據(jù)庫報超時錯誤
本文針對Springboot2.x與Mybatis3.x結(jié)合使用時,Hikari連接數(shù)據(jù)庫出現(xiàn)超時錯誤的問題進行了深入分析,并提供了一系列有效的解決方法,感興趣的可以了解一下2023-11-11SpringBoot整合Swagger3生成接口文檔過程解析
這篇文章主要介紹了SpringBoot整合Swagger3生成接口文檔過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07Java原生服務(wù)器接收上傳文件 不使用MultipartFile類
這篇文章主要為大家詳細介紹了Java原生服務(wù)器接收上傳文件,不使用MultipartFile類,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09