Java中的MessageDigest類加密詳解
MessageDigest類
MessageDigest 類是一個(gè)引擎類,它是為了提供諸如 SHA1 或 MD5 等密碼上安全的報(bào)文摘要功能而設(shè)計(jì)的。
密碼上安全的報(bào)文摘要可接受任意大小的輸入(一個(gè)字節(jié)數(shù)組),并產(chǎn)生固定大小的輸出,該輸出稱為一個(gè)摘要或散列。
創(chuàng)建MessageDigest對(duì)象
計(jì)算信息摘(即散列碼)要做的第一步是創(chuàng)建 MessageDigest對(duì)象 實(shí)例。
像所有的引擎類一樣,獲取某類報(bào)文摘要算法(即散列算法,比如MD5)的 MessageDigest 對(duì)象的途徑是調(diào)用 MessageDigest 類中的 getInstance 靜態(tài) factory 方法:
public static MessageDigest getInstance(String algorithm)
- 注意1:即時(shí)給定MessageDigest的實(shí)現(xiàn)是不可復(fù)制的,則仍然能夠通過(guò)getInstance方法實(shí)例化幾個(gè)實(shí)例計(jì)算來(lái)同時(shí)進(jìn)行摘要信息的計(jì)算。
- 注意2:由于歷史原因,此類是抽象的,是從 MessageDigestSpi 擴(kuò)展的。應(yīng)用程序開發(fā)人員只應(yīng)該注意在此 MessageDigest 類中定義的方法;超類中的所有方法是供希望提供自己的信息摘要算法實(shí)現(xiàn)的加密服務(wù)提供者使用的。
- 注意3:MessageDigest并不是單實(shí)例的。如下代碼所示:
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();
}運(yùn)行結(jié)果
mdTemp1==mdTemp2?:false
mdTemp2==mdTemp3?:false
注意:算法名不區(qū)分大小寫。例如,以下所有調(diào)用都是相等的:
MessageDigest.getInstance("SHA");
MessageDigest.getInstance("sha");
MessageDigest.getInstance("sHa");方法摘要
| 方法 | 摘要 |
| Object | clone() 如果實(shí)現(xiàn)是可復(fù)制的,則返回一個(gè)副本。 |
| byte[] | digest() 通過(guò)執(zhí)行諸如填充之類的最終操作完成哈希計(jì)算。 |
| byte[] | digest(byte[] input) 使用指定的字節(jié)數(shù)組對(duì)摘要進(jìn)行最后更新,然后完成摘要計(jì)算。 |
| int | digest(byte[] buf, int offset, int len) 通過(guò)執(zhí)行諸如填充之類的最終操作完成哈希計(jì)算。 |
| String | getAlgorithm() 返回標(biāo)識(shí)算法的獨(dú)立于實(shí)現(xiàn)細(xì)節(jié)的字符串。 |
| int | getDigestLength() 返回以字節(jié)為單位的摘要長(zhǎng)度,如果提供程序不支持此操作并且實(shí)現(xiàn)是不可復(fù)制的,則返回 0。 |
| static MessageDigest | getInstance(String algorithm) 生成實(shí)現(xiàn)指定摘要算法的 MessageDigest 對(duì)象。 |
| static MessageDigest | getInstance(String algorithm, Provider provider) 生成實(shí)現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對(duì)象,如果該算法可從指定的提供程序得到的話。 |
| static MessageDigest | getInstance(String algorithm, String provider) 生成實(shí)現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對(duì)象,如果該算法可從指定的提供程序得到的話。 |
| Provider | getProvider() 返回此信息摘要對(duì)象的提供程序。 |
| static boolean | isEqual(byte[] digesta, byte[] digestb) 比較兩個(gè)摘要的相等性。 |
| void | reset() 重置摘要以供再次使用。 |
| String | toString() 返回此信息摘要對(duì)象的字符串表示形式。 |
| 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("標(biāo)題不能為空");
}
if(mFile==null){
throw new ServiceException("不允許上傳空文件");
}
byte[] bytes ;
String digests= null;
try {
//將文件摘要轉(zhuǎn)為字節(jié)
bytes = mFile.getBytes();
//將摘要后的字節(jié)數(shù)組進(jìn)行MD5加密
digests = DigestUtils.md5DigestAsHex(bytes);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException("文件上傳失敗");
}
Integer rows = attachementsDao.getRowCountByDigest(digests);
if(rows>0){
throw new ServiceException("文件已上傳,請(qǐng)勿重復(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("新增失敗");
}
}運(yùn)行結(jié)果
鹽值:c971db77-f109-401a-95f7-49b0f2bf0863
密碼:123456
鹽值加密:c971db77-f109-401a-95f7-49b0f2bf0863123456
加密后:525f7296b1ca744ca751344a4196ad17
到此這篇關(guān)于Java中的MessageDigest類加密詳解的文章就介紹到這了,更多相關(guān)MessageDigest類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于@CacheEvict無(wú)法解決分頁(yè)緩存清除的解決思路
這篇文章主要介紹了關(guān)于@CacheEvict無(wú)法解決分頁(yè)緩存清除的解決思路,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java中的ReadWriteLock讀寫鎖實(shí)例詳解
Java中的ReadWriteLock讀寫鎖,它是一種讀寫分離的鎖機(jī)制,適用于讀多寫少的場(chǎng)景,本文通過(guò)實(shí)例代碼給大家介紹Java中的ReadWriteLock讀寫鎖,感興趣的朋友跟隨小編一起看看吧2026-03-03
Java后端學(xué)習(xí)精華之TCP通信傳輸協(xié)議詳解
TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會(huì)保證數(shù)據(jù)不丟包、不亂序。TCP全名是Transmission Control Protocol,它是位于網(wǎng)絡(luò)OSI模型中的第四層2021-09-09
關(guān)于java連接池/線程池/內(nèi)存池/進(jìn)程池等匯總分析
這篇文章主要介紹了關(guān)于java連接池/線程池/內(nèi)存池/進(jìn)程池等匯總分析,本文將介紹池技術(shù)的由來(lái)、原理、優(yōu)缺點(diǎn)以及常見(jiàn)的池技術(shù)類型,需要的朋友可以參考下2023-04-04

