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