1. 程式人生 > >Java加密算法

Java加密算法

ips stat 自帶 import catch ase 默認 目錄 產生

JDK中帶有部分加密算法的實現類,主要的是java.security和javax.crypto包下的類,還可以使用Bouncy Castle(豐富JDK中加密算法的不足)jar包是:bcprov-jdk15on-1.57.jar和Commons Codec(簡化JDK中加密的操作)jar包是:commons-codec-1.10.jar

Base64

Base64用於網絡中傳輸的數據進行編碼,嚴格意義上屬於編碼的格式,有64個字符的對應的編碼,Base64就是將內容按照該格式進行編碼。可以對數據編碼和解碼,是可逆的,安全度較低,不過,也可以作為最基礎最簡單的加密算法用於加密要求較弱的情況

Base64可以使用JDk中自帶的類實現,還可以使用Bouncy Castle(簡稱bc)或Commons Codec(簡稱cc)實現

加密數據:

private static String src="Hello Base64";

導入的類:

import java.io.IOException;

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

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

JDk實現主要使用用BASE64Encoder和BASE64Decoder類的方法(註意在Eclipse中使用JDK的Base64可能會出現找不到的問題,是因為Base64Encoder並不屬於JDK標準庫範疇,但是又包含在了JDK中,需要我們手動導入\jre\lib目錄下的rt.jar包即可

):

    public static void jdkBase64(){
        try {
            BASE64Encoder encoder=new BASE64Encoder();
            String encode = encoder.encode(src.getBytes());
            System.out.println("encode: "+encode);
            
            BASE64Decoder decoder=new BASE64Decoder();
            String decode
=new String(decoder.decodeBuffer(encode)); System.out.println("decode: "+decode); } catch (IOException e) { e.printStackTrace(); } }

bc實現主要是用Base64類的方法:

    public static void bouncybastleBase64(){
        byte[] encode = org.bouncycastle.util.encoders.Base64.encode(src.getBytes());
        System.out.println("encode: "+new String(encode));
        
        byte[] decode = org.bouncycastle.util.encoders.Base64.decode(encode);
        System.out.println("decode: "+new String(decode));
    }

cc實現也是用Base64類,不過與bc的是不一樣的,不同包中的類,只是名字一樣:

    public static void commonscodecBase64(){
        byte[] encode=Base64.encodeBase64(src.getBytes());
        System.out.println("encode: "+new String(encode));  //需要轉化為String
        
        byte[] decode = Base64.decodeBase64(encode);
        System.out.println("decode: "+new String(decode));
    }

摘要算法

摘要算法主要分為MD,SHA和Hmac算法,摘要算法其實是用於效驗數據完整性的,我們在下載某些文件時,會有MD5和SHA1值提供我們效驗下載的文件是否完整,可以用於根據數據生成其唯一的摘要值,無法根據摘要值知道原數據,屬於不可逆的

MD:

技術分享

加密數據:

private static String src="Hello MD";

導入的類:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

JDK有MD2和MD5的實現,使用的是MessageDigest類,而沒有MD4的實現:

    public static void jdkMD5(){
        try {
            MessageDigest md=MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(src.getBytes());
            System.out.println("JDK MD5: "+Hex.encodeHexString(digest));           //使用的是cc中帶的Hex需要轉換為十六進制
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        
    }
    
    public static void jdkMD2(){
        try {
            MessageDigest md=MessageDigest.getInstance("MD2");
            byte[] digest = md.digest(src.getBytes());
            System.out.println("JDK MD2: "+Hex.encodeHexString(digest));   
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        
    }

而bc這三種都有,使用的是Digest 類:

    public static void bcMD4(){
        //方式一
//        Digest digest=new MD4Digest();
//        digest.update(src.getBytes(), 0, src.getBytes().length);
//        byte[] md4Bytes=new byte[digest.getDigestSize()];
//        digest.doFinal(md4Bytes, 0);
//        System.out.println("BC MD4: "+org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
        
        
      //方式二
        try {
            Security.addProvider(new BouncyCastleProvider());
            MessageDigest md=MessageDigest.getInstance("MD4");
            byte[] digest = md.digest(src.getBytes());
            System.out.println("BC MD4: "+Hex.encodeHexString(digest));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    
    public static void bcMD5(){
        Digest digest=new MD5Digest();
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte[] md4Bytes=new byte[digest.getDigestSize()];
        digest.doFinal(md4Bytes, 0);
        System.out.println("BC MD5: "+org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));        //bc中帶的Hex
    }
    
    public static void bcMD2(){
        Digest digest=new MD2Digest();
        digest.update(src.getBytes(), 0, src.getBytes().length);
        byte[] md4Bytes=new byte[digest.getDigestSize()];
        digest.doFinal(md4Bytes, 0);
        System.out.println("BC MD2: "+org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
    }

cc和JDK是一樣的,畢竟是對JDK加密的簡化,直接使用DigestUtils中的方法,很簡單,而且前兩種方法還需要將MD值轉換為十六進制,cc直接就幫我們轉了:

    public static void ccMD2(){        //有方法直接就可以轉換十六進制
        System.out.println("CC MD2: "+DigestUtils.md2Hex(src.getBytes()));
    }
    
    public static void ccMd5(){
        System.out.println("CC MD5: "+DigestUtils.md5Hex(src.getBytes()));
    }

SHA:

這裏只是使用SHA-1,其他類型類似

技術分享

加密數據:

private static String src="Hello SHA";

要導入的類:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;import sun.security.provider.SHA;

JDK實現方式(同樣是使用MessageDigest):

    public static void jdkSHA1(){
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA");
            digest.update(src.getBytes());
            System.out.println("JDK SHA1: "+Hex.encodeHexString(digest.digest()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

bc的實現方式(同樣是Digest 類):

    public static void mcSHA1(){
        Digest digest=new SHA1Digest();
        digest.update(src.getBytes(),0,src.getBytes().length);
        byte[] sha1Byte1=new byte[digest.getDigestSize()];
        digest.doFinal(sha1Byte1, 0);
        System.out.println("MC SHA1:"+org.bouncycastle.util.encoders.Hex.toHexString(sha1Byte1));
    }

cc的實現方式:

    public static void ccsha(){
        System.out.println("CC sha1:"+DigestUtils.sha1Hex(src));
    }

Hmac(含有密鑰的摘要算法,也有簡稱mac,密鑰不同摘要也不同):

技術分享

要加密的數據:

private static String src="Hello HMAC";

要導入的類:

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

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;

JDK的實現方式:

    public static void jdkHmacMD5(){
        try {
            KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacMD5");  //初始化KeyGenerator
            SecretKey secretKey=keyGenerator.generateKey(); //產生密鑰
            //byte[] key=secretKey.getEncoded();     //獲得密鑰(默認生成)
            
            byte[] key=Hex.decodeHex(new char[]{‘a‘,‘a‘,‘a‘,‘a‘,‘a‘,‘a‘,‘a‘,‘a‘,‘a‘,‘a‘});  //手動生成密鑰(十位)
            
            SecretKey secretKey2=new SecretKeySpec(key, "HmacMD5"); //還原密鑰
            Mac mac=Mac.getInstance(secretKey2.getAlgorithm());  //實例化mac
            //初始化mac
            mac.init(secretKey2);
            byte[] hmacMD5Bytes=mac.doFinal(src.getBytes());
            System.out.println("jdk hmacMD5: "+Hex.encodeHexString(hmacMD5Bytes));
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

bc的實現方式:

    public static void bcHmacMd5(){
        HMac hMac=new HMac(new MD5Digest());
        hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa")));  //需要十位密鑰
        hMac.update(src.getBytes(),0,src.getBytes().length);
        
        byte[] hmacMD5=new byte[hMac.getMacSize()];
        hMac.doFinal(hmacMD5, 0);
        System.out.println("bc hmacMD5: "+org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5));

    }

Java加密算法