非對稱加密(RSA、DH)

常用的Java加密技術和核心代碼系列:

Base64以及關於Base64遇到的坑   https://blog.csdn.net/haponchang/article/details/106094115

消息摘要算法  https://blog.csdn.net/haponchang/article/details/106096542

對稱加密(DES、3DES、AES、PBE) https://blog.csdn.net/haponchang/article/details/106096766

非對稱加密(RSA、DH) https://blog.csdn.net/haponchang/article/details/106097998

數字簽名證書 https://blog.csdn.net/haponchang/article/details/106098779

 

概念

        非對稱加密算法需要兩個密鑰來進行加密和解密,分別是公鑰和私鑰。需要注意的一點,這個公鑰和私鑰必須是一對的,如果用公鑰對數據進行加密,那麼只有使用對應的私鑰才能解密,反之亦然。由於加密和解密使用的是兩個不同的密鑰,因此,這種算法叫做非對稱加密算法。

常見對稱加密算法有RSA、DH。

 

RSA

RSA 算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但是想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作爲加密密鑰。

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

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

public class RSAStrategy {
    private RSAPublicKey rsaPublicKey;
    private RSAPrivateKey rsaPrivateKey;

    public String encode(String src) {
        try {
            //初始化密鑰
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance ("RSA");
            keyPairGenerator.initialize (512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair ( );
            rsaPublicKey = (RSAPublicKey) keyPair.getPublic ( );
            rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate ( );

            //私鑰加密 公鑰解密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec
                    = new PKCS8EncodedKeySpec (rsaPrivateKey.getEncoded ( ));
            KeyFactory keyFactory = KeyFactory.getInstance ("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate (pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance ("RSA");
            cipher.init (Cipher.ENCRYPT_MODE, privateKey);
            byte[] resultBytes = cipher.doFinal (src.getBytes ( ));

            //私鑰解密 公鑰加密
//          X509EncodedKeySpec x509EncodedKeySpec =
//                  new X509EncodedKeySpec(rsaPublicKey.getEncoded());
//          KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//          PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
//          Cipher cipher = Cipher.getInstance("RSA");
//          cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//          byte[] resultBytes = cipher.doFinal(src.getBytes());

            return Hex.encodeHexString (resultBytes);
        } catch (Exception e) {
            e.printStackTrace ( );
        }

        return null;
    }

    public String decode(String src) {
        try {
            //私鑰加密 公鑰解密
            X509EncodedKeySpec x509EncodedKeySpec =
                    new X509EncodedKeySpec (rsaPublicKey.getEncoded ( ));
            KeyFactory keyFactory = KeyFactory.getInstance ("RSA");
            PublicKey publicKey = keyFactory.generatePublic (x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance ("RSA");
            cipher.init (Cipher.DECRYPT_MODE, publicKey);
            byte[] resultBytes = cipher.doFinal (Hex.decodeHex (src.toCharArray ( )));

            //私鑰解密 公鑰加密
//          PKCS8EncodedKeySpec pkcs8EncodedKeySpec
//              = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
//          KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//          PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//          Cipher cipher = Cipher.getInstance("RSA");
//          cipher.init(Cipher.DECRYPT_MODE, privateKey);
//          byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));

            return new String (resultBytes);
        } catch (Exception e) {
            e.printStackTrace ( );
        }
        return null;
    }

}

 

DH

        DH,全稱爲“Diffie-Hellman”,他是一種確保共享KEY安全穿越不安全網絡的方法,也就是常說的密鑰一致協議。由公開密鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。簡單的說就是允許兩名用戶在公開媒體上交換信息以生成“一致”的、可以共享的密鑰。也就是由甲方產出一對密鑰(公鑰、私鑰),乙方依照甲方公鑰產生乙方密鑰對(公鑰、私鑰)。
以此爲基線,作爲數據傳輸保密基礎,同時雙方使用同一種對稱加密算法構建本地密鑰(SecretKey)對數據加密。這樣,在互通了本地密鑰(SecretKey)算法後,甲乙雙方公開自己的公鑰,使用對方的公鑰和剛纔產生的私鑰加密數據,同時可以使用對方的公鑰和自己的私鑰對數據解密。不單單是甲乙雙方兩方,可以擴展爲多方共享數據通訊,這樣就完成了網絡交互數據的安全通訊!

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

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

public class DHStrategy {
    private Cipher cipher;
    private SecretKey receiverSecretKey;

    public String encode(String src) {
        try {
            //初始化發送方密鑰
            KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance ("DH");
            senderKeyPairGenerator.initialize (512);
            KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair ( );
            PrivateKey senderPrivateKey = senderkeyPair.getPrivate ( );
            byte[] senderPublicKeyBytes = senderkeyPair.getPublic ( ).getEncoded ( );//發送方的公鑰

            //初始化接收方密鑰,用發送方的公鑰
            KeyFactory receiverKeyFactory = KeyFactory.getInstance ("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec (senderPublicKeyBytes);
            PublicKey receiverPublicKey = receiverKeyFactory.generatePublic (x509EncodedKeySpec);
            DHParameterSpec dhParameterSpec =
                    ((DHPublicKey) receiverPublicKey).getParams ( );
            KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance ("DH");
            receiverKeyPairGenerator.initialize (dhParameterSpec);
            KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair ( );
            PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate ( );
            byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic ( ).getEncoded ( );

            KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance ("DH");
            receiverKeyAgreement.init (receiverPrivateKey);
            receiverKeyAgreement.doPhase (receiverPublicKey, true);
            receiverSecretKey = receiverKeyAgreement.generateSecret ("DES");

            //發送方拿到接收方的public key就可以做加密了
            KeyFactory senderKeyFactory = KeyFactory.getInstance ("DH");
            x509EncodedKeySpec = new X509EncodedKeySpec (receiverPublicKeyBytes);
            PublicKey senderPublicKey = senderKeyFactory.generatePublic (x509EncodedKeySpec);
            KeyAgreement senderKeyAgreement = KeyAgreement.getInstance ("DH");
            senderKeyAgreement.init (senderPrivateKey);
            senderKeyAgreement.doPhase (senderPublicKey, true);
            SecretKey senderSecretKey = senderKeyAgreement.generateSecret ("DES");

            if (Objects.equals (receiverSecretKey, senderSecretKey)) {
                cipher = Cipher.getInstance ("DES");
                cipher.init (Cipher.ENCRYPT_MODE, senderSecretKey);
                byte[] result = cipher.doFinal (src.getBytes ( ));
                return Hex.encodeHexString (result);
            }

        } catch (Exception e) {
            e.printStackTrace ( );
        }

        return null;
    }

    public String decode(String src) {
        try {
            cipher.init (Cipher.DECRYPT_MODE, receiverSecretKey);
            byte[] result = Hex.decodeHex (src.toCharArray ( ));
            return new String (cipher.doFinal (result));
        } catch (Exception e) {
            e.printStackTrace ( );
        }

        return null;
    }

}

 

 

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