JAVA密碼編譯演算法- 非對稱式加密演算法(DH,RSA)的詳細介紹_java

來源:互聯網
上載者:User

非對稱密碼概念

1、與對稱式加密演算法的主要差別在於,加密和解密的密鑰不相同,一個公開(公開金鑰),一個保密(私密金鑰)。主要解決了對稱式加密演算法密鑰分配管理的問題,提高了演算法安全性。

2、非對稱式加密演算法的加密、解密的效率比較低。在演算法設計上,非對稱式加密演算法對待加密的資料長度有著苛刻的要求。例如RSA演算法要求待加密的資料不得大於53個位元組。

3、非對稱式加密演算法主要用於 交換對稱式加密演算法的密鑰,而非資料交換

4、java6提供實現了DH和RSA兩種演算法。Bouncy Castle提供了E1Gamal演算法支援。除了上述三種演算法還有一個ECC演算法,目前沒有相關的開源組件提供支援

需要兩個密鑰進行加密或解密,分為公開金鑰和私密金鑰

特點:安全性高,速度慢

用途

【金鑰交換(DH)】

雙方在沒有確定共同密鑰的情況下,產生密鑰,不提供加密工作,加解密還需要其他對稱式加密演算法實現

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)】【數位簽章(RSA)】

RSA演算法晚於DH演算法,這五個字母全都是人名首字母.DH演算法是第一個非對稱密碼體系.

RSA演算法運算速度慢,不適宜加密大量資料.一種解決方案是,將RSA跟對稱式加密方式混合使用,將資料使用對稱式加密方式加密,對稱式加密的密鑰使用RSA演算法加密,因為密鑰很短,所以時間費不了太多.實際上,對稱式加密方式唯一的弊端就是密鑰不好傳遞,對稱式加密方式也很難破解.

RSA的適用情景一:

(1)伺服器產生一個公開金鑰和一個私密金鑰,把公開金鑰公開了.

(2)用戶端使用公開金鑰把資料進行加密,上交伺服器.別人是沒法理解加密後的資料的.

(3)伺服器使用私密金鑰將資料解密,查看使用者提交的資料.

這種情景下,公開金鑰像是一個信箱,每個人都可以往這個信箱裡面放信,但是這個信箱裡面的信只有掌握信箱鑰匙的人才能開箱查看.

RSA適用情景二:

(1)皇上產生一個公開金鑰和一個密鑰,把公開金鑰公開了.

(2)皇上發布了一封詔書,昭告天下.詔書右下角有兩串數字,第一串數字是一個隨機串,第二串數字是用私密金鑰加密第一串數字所得的結果.

(3)有人不相信這詔書是皇上寫的,就把第二串數字使用公開金鑰解密,解密之後發現跟第一串數字一樣,說明確實是皇上寫的,因為一般人沒有密鑰,也就沒法加密那些能夠用公開金鑰解密的資料.

這種情境下,公開金鑰用於解密,私密金鑰用於加密,這可以用於發布公告時,證明這個公告確實是某個人發的.相當於簽名.

實際上,簽名沒有必要特別長,一般情況下,簽名是定長的,要想定長,可以使用MessageDigest演算法,如MD5和SHA系列.所以就有了多種簽名演算法,如MD5withRSA等.

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));  }}

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.