Java單向加密(不可逆加密)


MD5、SHA、HMAC這三種加密算法,是非可逆加密,就是不可解密的加密方法。我們通常只把他們作為加密的基礎。單純的以上三種的加密並不可靠。 

MD5 
MD5 -- message-digest algorithm 5 (信息-摘要算法)縮寫,廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD5后都能生成唯一的MD5值。好比現在的ISO校驗,都是MD5校驗。怎么用?當然是把ISO經過MD5后產生MD5的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放着MD5的串。就是用來驗證文 件是否一致的。 

 

 

 Java實現代碼jdk版本的

import sun.misc.BASE64Encoder;

import java.security.MessageDigest;


public class Test {

    public static void main(String[] args) throws Exception{

        encryptMD5("HELLO".getBytes());
        System.out.println(new BASE64Encoder().encode(encryptMD5("HELLO".getBytes())));

    }
    public static byte[] encryptMD5(byte[] data) throws Exception {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(data);
        return md5.digest();
    }
}

通常我們不直接使用上述MD5加密。通常將MD5產生的字節數組交給BASE64再加密一把,得到相應的字符串。

spring也提供了 封裝類:

DigestUtils.md5DigestAsHex(password.getBytes())

 

SHA 
SHA(Secure Hash Algorithm,安全散列算法),數字簽名等密碼學應用中重要的工具,被廣泛地應用於電子商務等信息安全領域。雖然,SHA與MD5通過碰撞法都被破解了, 但是SHA仍然是公認的安全加密算法,較之MD5更為安全。

 java 實現SHA加密jdk版

  /**
     *  利用java原生的摘要實現SHA256加密
     * @param str 加密后的報文
     * @return
     */
    public static String getSHA256StrJava(String str){
        MessageDigest messageDigest;
        String encodeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodeStr = byte2Hex(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodeStr;
    }

    /**
     * 將byte轉為16進制
     * @param bytes
     * @return
     */
    private static String byte2Hex(byte[] bytes){
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i=0;i<bytes.length;i++){
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length()==1){
                //1得到一位的進行補0操作
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }

Apache實現的:

 

<dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>${common-codec.version}</version>
</dependency>
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;


public class Test {
    
    /**
     * Apache SHA
     */
    public static String getSHA256Str(String str){
        MessageDigest messageDigest;
        String encdeStr = "";
        try {
            messageDigest = DigestUtils.getSha256Digest();
            byte[] hash=DigestUtils.digest(messageDigest,str.getBytes("UTF-8"));
            encdeStr = Hex.encodeHexString(hash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encdeStr;
    }


}

HMAC 
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個 標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然后傳輸。接收方利用與發送方共享的密鑰進行鑒別認證 等。 

 

 

 Java實現hmac

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class Test {

    public static void main(String[] args) throws Exception{

        String secrekey=initMacKey();
        System.out.println(new String(encryptHMAC("hello".getBytes(),secrekey)));
    }

    /**
     * 初始化HMAC密鑰
     * @return
     * @throws Exception
     */
    public static String initMacKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
        SecretKey secretKey = keyGenerator.generateKey();
        return new BASE64Encoder().encode(secretKey.getEncoded());
    }
    /**
     * HMAC加密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(new BASE64Decoder().decodeBuffer(key), "HmacSHA256");
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);
        return mac.doFinal(data);
    }
}

apache 實現的工具類

同樣還是commons-codec包

具體可以參看包里的org.apache.commons.codec.digest.HmacUtils類

下面給出一個自封裝的HmacUtils工具類

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @Describe: Hmac加密工具類
 */
public class HmacUtils {


    /**
     * 加密生成簽名
     * @param data 簽名的格式
     * @param key  秘鑰
     * @return
     */
    public static byte[] hmacSHA512(byte[] data, String key) {
        try {
            SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"),
                    "HmacSHA512");
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return mac.doFinal(data);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * base64編碼的變體,由於base64中的=、/和+不適合Url傳遞,
     * 因此需要將這三個符號替換掉,規則是去掉=,+替換為-,/替換為_
     * @param stringBytes  hmac(hmacSHA512)
     * @return
     */
    public static String base64Url(byte[] stringBytes) {
        try {

            String base64Str = Base64.encodeBase64String(stringBytes);
            base64Str = base64Str.replace("=", "");
            base64Str = base64Str.replace("+", "-");
            base64Str = base64Str.replace("/", "_");

            return base64Str;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    /**
     * SHA512 加密
     * @param strText (用戶密碼明文 + salt)
     * @return
     */
    public static byte[] sha512(final String strText) {
        // 是否是有效字符串
        if (strText != null && strText.length() > 0) {
            try {
                // SHA 加密開始
                // 創建加密對象 並指定加密類型
                MessageDigest messageDigest = MessageDigest
                        .getInstance("SHA-512");
                // 傳入要加密的字符串
                messageDigest.update(strText.getBytes("UTF-8"));
                // 得到 byte 數組
                return messageDigest.digest();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Base64加密
     * @param stringbytes
     * @return
     */
    public static String base64(byte[] stringbytes) {
        try {
            String base64Str = Base64.encodeBase64String(stringbytes);
            return base64Str;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
}

以上就是這三種單向加密的介紹。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM