JAVA加密算法(4)- 非對稱加密算法(DH,RSA)

非對稱密碼概念

發送者使用接收者的公鑰加密,接收者使用本身的私鑰解密。java

須要兩個密鑰進行加密或解密,分爲公鑰和私鑰算法

特色:安全性高,速度慢數組

經常使用算法

  • DH密鑰交換算法安全

  • RSA算法工具

  • ElGamal算法那加密

用途

  • 密鑰交換(DH)code

雙方在沒有肯定共同密鑰的狀況下,生成密鑰,不提供加密工做,加解密還須要其餘對稱加密算法實現ip

  • 加密/解密(RSA)ci

  • 數字簽名(RSA)get

DH算法示例

import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

//1 生成源密鑰
//2 把源公鑰交給目標,目標經過源公鑰,生成目標公鑰和私鑰
//3 把目標公鑰交給源
//4 雙方使用對方的公鑰和和本身的私鑰,生成本地密鑰
//5 若是雙方生成本地密鑰相同則完成密鑰交換
public class DHUtil {

    public static final String PUBLIC_KEY = "DH_Public_Key";
    public static final String PRIVATE_KEY = "DH_Private_key";

    /**
     * 生成源密鑰對
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initSourceKey() throws Exception{
        //建立KeyPairGenerator的實例,選用DH算法
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");

        //初始化密鑰長度,默認1024,可選範圍512-65536 & 64的倍數
        keyPairGenerator.initialize(1024);

        //生成密鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
        DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

        //將密鑰對放入Map
        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, dhPublicKey);
        keyMap.put(PRIVATE_KEY, dhPrivateKey);
        return keyMap;
    }

    /**
     * 經過源公鑰 生成 目標密鑰對
     * @param sourcePublicKey
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initTargetKey(byte[] sourcePublicKey) throws Exception {

        KeyFactory keyFactory = KeyFactory.getInstance("DH");

        //經過源公鑰,生成keySpec,使用KeyFactory生成源PublicKey相關信息
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(sourcePublicKey);
        DHPublicKey sourcePublic = (DHPublicKey) keyFactory.generatePublic(keySpec);

        DHParameterSpec dhPublicKeyParams = sourcePublic.getParams();

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
        keyPairGenerator.initialize(dhPublicKeyParams);

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
        DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

        //將密鑰對放入Map
        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, dhPublicKey);
        keyMap.put(PRIVATE_KEY, dhPrivateKey);
        return keyMap;
    }

    /**
     * 使用一方的公鑰和另外一方的私鑰,生成本地密鑰
     * @return
     */
    public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{
        KeyFactory keyFactory = KeyFactory.getInstance("DH");

        //經過A公鑰,生成keySpec,使用KeyFactory生成A PublicKey相關信息
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        //經過B私鑰,生成B PrivateKey相關信息
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //經過KeyAgreement對A的PublicKey和B的PrivateKey進行加密
        KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
        keyAgreement.init(privateKey);
        keyAgreement.doPhase(publicKey,true);


        return keyAgreement.generateSecret("AES").getEncoded();//算法使用對稱加密算法(DES,DESede,AES)
        //return keyAgreement.generateSecret();                // 也能夠不選擇算法,使用默認方法計算
    }

    //獲取公鑰字節數組
    public static byte[] getPublicKey(Map<String,Object> map){
        return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
    }

    //獲取私鑰字節數組
    public static byte[] getPrivateKey(Map<String,Object> map){
        return ((DHPrivateKey) map.get(PRIVATE_KEY)).getEncoded();
    }

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

        byte[] source_public_key;
        byte[] source_private_key;
        byte[] source_local_key;

        byte[] target_public_key;
        byte[] target_private_key;
        byte[] target_local_key;

        Map<String, Object> sourceKey = initSourceKey();
        source_public_key = getPublicKey(sourceKey);
        source_private_key = getPrivateKey(sourceKey);

        System.out.println("源公鑰:"+BytesToHex.fromBytesToHex(source_public_key));
        System.out.println("源私鑰:"+BytesToHex.fromBytesToHex(source_private_key));

        Map<String, Object> targetKey = initTargetKey(getPublicKey(sourceKey));
        target_public_key = getPublicKey(targetKey);
        target_private_key = getPrivateKey(targetKey);

        System.out.println("目標公鑰:"+BytesToHex.fromBytesToHex(target_public_key));
        System.out.println("目標私鑰:"+BytesToHex.fromBytesToHex(target_private_key));

        source_local_key = generateLocalSecretKey(target_public_key, source_private_key);
        target_local_key = generateLocalSecretKey(source_public_key, target_private_key);

        System.out.println("源本地密鑰:"+BytesToHex.fromBytesToHex(source_local_key));
        System.out.println("目標本地密鑰:"+BytesToHex.fromBytesToHex(target_local_key));
    }
}

RSA 加密/解密 示例

公鑰加密,私鑰解密

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA加密工具
 */
public class RSAUtil {

    public static final String PUBLIC_KEY = "RSA_Public_Key";
    public static final String PRIVATE_KEY = "RSA_Private_Key";

    /**
     * 初始化密鑰
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initKey() throws Exception{
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);//512-65536 & 64的倍數
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    public static RSAPublicKey getPublicKey(Map<String,Object> keyMap) {
        return (RSAPublicKey) keyMap.get(PUBLIC_KEY);
    }

    public static RSAPrivateKey getPrivateKey(Map<String,Object> keyMap){
        return (RSAPrivateKey) keyMap.get(PRIVATE_KEY);
    }

    /**
     * 使用公鑰對數據進行加密
     * @param data
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 使用私鑰解密
     * @param data
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        String data = "周杰倫-東風破";
        Map<String, Object> keyMap = initKey();

        byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap));
        System.out.println("加密後的內容:"+BytesToHex.fromBytesToHex(miwen));

        byte[] plain = decrypt(miwen, getPrivateKey(keyMap));
        System.out.println("解密後的內容:"+new String(plain));

    }
}
相關文章
相關標籤/搜索