MessageDigest(加密)

MessageDigest類

MessageDigest 類是一個引擎類,它是爲了提供諸如 SHA1 或 MD5 等密碼上安全的報文摘要功能而設計的。密碼上安全的報文摘要可接受任意大小的輸入(一個字節數組),併產生固定大小的輸出,該輸出稱爲一個摘要或散列。

創建MessageDigest對象

計算信息摘(即散列碼)要做的第一步是創建 MessageDigest對象 實例。像所有的引擎類一樣,獲取某類報文摘要算法(即散列算法,比如MD5)的  MessageDigest 對象的途徑是調用 MessageDigest 類中的 getInstance 靜態 factory 方法:

    public static MessageDigest getInstance(String algorithm)

注意1:即時給定MessageDigest的實現是不可複製的,則仍然能夠通過getInstance方法實例化幾個實例計算來同時進行摘要信息的計算。

注意2:由於歷史原因,此類是抽象的,是從 MessageDigestSpi 擴展的。應用程序開發人員只應該注意在此 MessageDigest 類中定義的方法;超類中的所有方法是供希望提供自己的信息摘要算法實現的加密服務提供者使用的。 

注意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();
 
            }

運行結果

mdTemp1==mdTemp2?:false
 
mdTemp2==mdTemp3?:false

注意:算法名不區分大小寫。例如,以下所有調用都是相等的:

MessageDigest.getInstance("SHA");
 
MessageDigest.getInstance("sha");
 
MessageDigest.getInstance("sHa");

 方法摘要

方法摘要
 Object clone() 
          如果實現是可複製的,則返回一個副本。
 byte[] digest() 
          通過執行諸如填充之類的最終操作完成哈希計算。
 byte[] digest(byte[] input) 
          使用指定的字節數組對摘要進行最後更新,然後完成摘要計算。
 int digest(byte[] buf, int offset, int len) 
          通過執行諸如填充之類的最終操作完成哈希計算。
 String getAlgorithm() 
          返回標識算法的獨立於實現細節的字符串。
 int getDigestLength() 
          返回以字節爲單位的摘要長度,如果提供程序不支持此操作並且實現是不可複製的,則返回 0。
static MessageDigest getInstance(String algorithm) 
          生成實現指定摘要算法的 MessageDigest 對象。
static MessageDigest getInstance(String algorithm, Provider provider) 
          生成實現指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。
static MessageDigest getInstance(String algorithm, String provider) 
          生成實現指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。
 Provider getProvider() 
          返回此信息摘要對象的提供程序。
static boolean isEqual(byte[] digesta, byte[] digestb) 
          比較兩個摘要的相等性。
 void reset() 
          重置摘要以供再次使用。
 String toString() 
          返回此信息摘要對象的字符串表示形式。
 void update(byte input) 
          使用指定的字節更新摘要。
 void update(byte[] input) 
          使用指定的字節數組更新摘要。
 void update(byte[] input, int offset, int len) 
          使用指定的字節數組,從指定的偏移量開始更新摘要。
 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 {
            //將文件摘要轉爲字節
			bytes = mFile.getBytes();
            //將摘要後的字節數組進行MD5加密
			digests = DigestUtils.md5DigestAsHex(bytes);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("文件上傳失敗");
		}
		Integer rows = attachementsDao.getRowCountByDigest(digests);
		if(rows>0){
			throw new ServiceException("文件已上傳,請勿重複上傳!"); 
		}
		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);
        //文件夾是否存在 不存在將創建
		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("新增失敗");
		}
	}

運行結果

鹽值:c971db77-f109-401a-95f7-49b0f2bf0863
密碼:123456
鹽值加密:c971db77-f109-401a-95f7-49b0f2bf0863123456
加密後:525f7296b1ca744ca751344a4196ad17

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章