密鑰分散原理代碼

參考文獻

   https://blog.csdn.net/u012598738/article/details/53158443

   https://blog.csdn.net/jimi_yuan/article/details/50589069

話不多說直接貼代碼

package com.people.test;

import sun.misc.BASE64Decoder;

/**
 *密鑰分算算法簡稱Diversify,是指將一個雙長度(一個長度密鑰爲8個字節)的主密鑰(MK),對數據進行分散處理,推導出一個雙長度的DES加密密鑰(DK)。該算法廣泛應用於現在的金融IC卡和其他對於安全要求高的行業。其DK推導過程如下:
 *     推導DK左半部分的方法是:
 *    1、將分散數據的最右8個字節作爲輸入數據;
 *      2、將MK作爲加密密鑰;
 *      3、用MK對輸入數據進行3DES運算,得到DK左半部分。
 *推導DK右半部分的方法是:
 *      1、將分散數據的最右8個字節求反,作爲輸入數據;
 *      2、將MK作爲加密密鑰;
 *       3、用MK對輸入數據進行3DES運算,得到DK右半部分
 *        最後將DK的左右部分各8個字節合併成雙長度的DK密鑰,即爲分散所求得的待使用的3DES密鑰
 * 
 * @author zhaozhiqiang
 *
 */
   public class DiversifyTest {
	   public static void main(String atg[]){
		  String ss= getTransKey("C4D689158AD9FB9D23105B91CE046D0E",
				  "CE046D0EC4D68915"); 
		   System.out.print(ss);
	   }
	   
	   
	   /**
	    * 密鑰分散算法
	    * @param workKey 這裏的workKey參數即前面提到的MK,
	    * @param random  random即前面提到的分散數據,都是16進制的數據
	    * @return
	    */
	   public static  String getTransKey(String workKey, String random) {
			if (null == workKey || 32 != workKey.length() || null == random || 16 != random.length()) {
			    return "位數操作有誤導";
			}

			try {
				// 計算過程密鑰左8字節
			    byte[] byteKey=new BASE64Decoder().decodeBuffer(workKey);
			    byte[] byteRandomRight = new byte[8];
			    byte[] byteRandomLeft = HexCodeUtils.decode(random);
			    for (int i = 0; i < byteRandomRight.length; i++) {
			        byteRandomRight[i] = (byte) ~byteRandomLeft[i];
			    }
                //加密
			    byte[] wkLeft = DESUtils.des3EncodeECB(byteKey, byteRandomLeft);
			    byte[] wkRight = DESUtils.des3EncodeECB(byteKey,byteRandomRight);
			   
			   
			    byte[] result = new byte[16];
			    //加密
			    for (int i = 0; i < wkLeft.length; i++) {
			        result[i] = wkLeft[i];
			    }

			    for (int i = 8; i < result.length; i++) {
			        result[i] = wkRight[i - 8];
			    }
			    return HexCodeUtils.toHexString(result,0,result.length);
			} catch (Exception e) {
				return ""+e;
			}

			
		    }
	
	   
	   
	
  }
package com.people.test;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
 * 3des加解密
 * @author zhaozhiqiang
 *
 */
public class DESUtils {
    public static void main(String[] args) throws Exception {
        byte[] key=new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");
        byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
        
        byte[] data="中國ABCabc123".getBytes("UTF-8");
        
        System.out.println("ECB加密解密");
        byte[] str3 = des3EncodeECB(key,data );
        byte[] str4 = des3DecodeECB(key,str3);
        System.out.println(new BASE64Encoder().encode(str3));
        System.out.println(new String(str4, "UTF-8"));
        System.out.println("-----------------------------");
        System.out.println("CBC加密解密");
        byte[] str5 = des3EncodeCBC(key, keyiv, data);
        byte[] str6 = des3DecodeCBC(key, keyiv, str5);
        System.out.println(new BASE64Encoder().encode(str5));
        System.out.println(new String(str6, "UTF-8"));
    }
    /**
     * ECB加密,不要IV
     * @param key 密鑰
     * @param data 明文
     * @return Base64編碼的密文
     * @throws Exception
     */
    public static byte[] des3EncodeECB(byte[] key, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * ECB解密,不要IV
     * @param key 密鑰
     * @param data Base64編碼的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] des3DecodeECB(byte[] key, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * CBC加密
     * @param key 密鑰
     * @param keyiv IV
     * @param data 明文
     * @return Base64編碼的密文
     * @throws Exception
     */
    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * CBC解密
     * @param key 密鑰
     * @param keyiv IV
     * @param data Base64編碼的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
}
package com.people.test;
/**
 * 字節數組互轉Hex編碼工具類
 * @author zhaozhiqiang
 *
 */
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.util.Arrays;
 
public class HexCodeUtils {
 
    public static void main(String[] args) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        String str = "測試";
        byte[] digest = md.digest(str.getBytes());
        System.out.println(HexCodeUtils.toHexString(digest));
        //db06c78d1e24cf708a14ce81c9b617ec
        byte[] bytes = HexCodeUtils.decode("db06c78d1e24cf708a14ce81c9b617ec");
        System.out.println(Arrays.equals(digest, bytes));
    }
 
    private static final HexEncoder encoder = new HexEncoder();
 
    public static String toHexString(byte[] data) throws IOException {
        return toHexString(data, 0, data.length);
    }
 
    public static String toHexString(byte[] data, int off, int length) throws IOException {
        byte[] encoded = encode(data, off, length);
        return new String(encoded);
    }
 
    public static byte[] encode(byte[] data) throws IOException {
        return encode(data, 0, data.length);
    }
 
    public static byte[] encode(byte[] data, int off, int length) throws IOException {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        encoder.encode(data, off, length, bOut);
        return bOut.toByteArray();
    }
 
    public static int encode(byte[] data, OutputStream out) throws IOException {
        return encoder.encode(data, 0, data.length, out);
    }
 
    public static int encode(byte[] data, int off, int length, OutputStream out) throws IOException {
        return encoder.encode(data, off, length, out);
    }
 
    public static byte[] decode(byte[] data) throws IOException {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        encoder.decode(data, 0, data.length, bOut);
        return bOut.toByteArray();
    }
 
    public static byte[] decode(String data) throws IOException {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        encoder.decode(data, bOut);
        return bOut.toByteArray();
    }
 
    public static int decode(String data, OutputStream out) throws IOException {
        return encoder.decode(data, out);
    }
}
 
class HexEncoder {
    private final byte[] encodingTable = {
            (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
            (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
    };
 
    private final byte[] decodingTable = new byte[128];
 
    private void initialiseDecodingTable() {
        for ( int i = 0; i < decodingTable.length; i++ ) {
            decodingTable[i] = (byte) 0xff;
        }
 
        for ( int i = 0; i < encodingTable.length; i++ ) {
            decodingTable[encodingTable[i]] = (byte) i;
        }
 
        decodingTable['A'] = decodingTable['a'];
        decodingTable['B'] = decodingTable['b'];
        decodingTable['C'] = decodingTable['c'];
        decodingTable['D'] = decodingTable['d'];
        decodingTable['E'] = decodingTable['e'];
        decodingTable['F'] = decodingTable['f'];
    }
 
    public HexEncoder() {
        initialiseDecodingTable();
    }
 
    private static boolean ignore(char c) {
        return c == '\n' || c == '\r' || c == '\t' || c == ' ';
    }
 
    public int encode(byte[] data, int off, int length, OutputStream out) throws IOException {
        for ( int i = off; i < (off + length); i++ ) {
            int v = data[i] & 0xff;
            out.write(encodingTable[(v >>> 4)]);
            out.write(encodingTable[v & 0xf]);
        }
        return length * 2;
    }
 
    public int decode(byte[] data, int off, int length, OutputStream out) throws IOException {
        byte b1, b2;
        int outLen = 0;
        int end = off + length;
 
        while ( end > off ) {
            if ( !ignore((char) data[end - 1]) ) break;
            end--;
        }
 
        int i = off;
        while ( i < end ) {
            while ( i < end && ignore((char) data[i]) ) i++;
            b1 = decodingTable[data[i++]];
 
            while ( i < end && ignore((char) data[i]) ) i++;
            b2 = decodingTable[data[i++]];
 
            if ( (b1 | b2) < 0 ) throw new IOException("invalid characters encountered in Hex data");
            out.write((b1 << 4) | b2);
            outLen++;
        }
        return outLen;
    }
 
    public int decode(String data, OutputStream out) throws IOException {
        byte b1, b2;
        int length = 0;
 
        int end = data.length();
        while ( end > 0 ) {
            if ( !ignore(data.charAt(end - 1)) ) break;
            end--;
        }
 
        int i = 0;
        while ( i < end ) {
            while ( i < end && ignore(data.charAt(i)) ) i++;
            b1 = decodingTable[data.charAt(i++)];
 
            while ( i < end && ignore(data.charAt(i)) ) i++;
            b2 = decodingTable[data.charAt(i++)];
 
            if ( (b1 | b2) < 0 ) throw new IOException("invalid characters encountered in Hex string");
            out.write((b1 << 4) | b2);
            length++;
        }
        return length;
    }
}

 

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