JAVA实现非对称加密:DH、RSA、ELGamal(相关API的应用)

版权声明:本文为博主 [小明同学爱思考] 原创文章,转载请注明出处。 https://blog.csdn.net/sinat_22840937/article/details/79941624

DH算法

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

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

/**
 * 非对称加密 - DH算法
 *
 * @author liuming
 * @create 2018/4/13
 */
public class DH {

    private static String srcMsg = "imooc security dh";

    public static void main(String[] args) {
        jdkDH(srcMsg);

    }

    public static void jdkDH(String srcMsg) {
        try {
            // 初始化发送方密钥
            KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            senderKeyPairGenerator.initialize(512);
            KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
            // 发送发公钥,需要发送给接收方
            byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();

            // 初始化接收方密钥
            KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc);
            PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
            DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams();
            KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            receiverKeyPairGenerator.initialize(dhParameterSpec);
            KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
            byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();

            // 密钥构建
            KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
            receiverKeyAgreement.init(receiverKeyPair.getPrivate());
            receiverKeyAgreement.doPhase(receiverPublicKey, true);
            SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");

            KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
            x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc);
            PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);

            KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
            senderKeyAgreement.init(senderKeyPair.getPrivate());
            senderKeyAgreement.doPhase(senderPublicKey, true);
            SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");

            // encrypt
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
            byte[] bytes = cipher.doFinal(srcMsg.getBytes());
            // output
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
            System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));

            // decrypt
            cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
            bytes = cipher.doFinal(bytes);
            // output
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

但是jdk1.8.0_161版本及以上,执行SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");会报如下错误:

java.security.NoSuchAlgorithmException: Unsupported secret key algorithm: DES
    at com.sun.crypto.provider.DHKeyAgreement.engineGenerateSecret(DHKeyAgreement.java:387)
    at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:648)
    at DH.jdkDH(DH.java:53)
    at DH.main(DH.java:26)

需要在执行时添加VM option内容为-Djdk.crypto.KeyAgreement.legacyKDF=true再执行即可。

RSA

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

import javax.crypto.Cipher;
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;

/**
 * RSA
 *
 * @author liuming
 * @create 2018/4/13
 */
public class RSA {

    private static String srcMsg = "imooc security rsa";

    public static void main(String[] args) {
        jdkRSA(srcMsg);

    }

    public static void jdkRSA(String srcMsg) {
        try {
            // 初始化发送方密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            System.out.println(Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println(Base64.encodeBase64String(rsaPrivateKey.getEncoded()));

            // 私钥加密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            // encrypt
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] bytes = cipher.doFinal(srcMsg.getBytes());
            // output
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
            System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));

            // 公钥解密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            // decrypt
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            bytes = cipher.doFinal(bytes);
            // output
            System.out.println(new String(bytes));


            // 公钥加密
            x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            bytes = cipher.doFinal(srcMsg.getBytes());
            // output
            encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
            System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));

            // 私钥解密
            pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            // encrypt
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            bytes = cipher.doFinal(bytes);
            // output
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

ELGamal

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;

/**
 * ELGamal
 *
 * @author liuming
 * @create 2018/4/13
 */
public class ELGamal {

    private static String srcMsg = "imooc security elgamal";

    public static void main(String[] args) {
        jdkELGamal(srcMsg);

    }

    public static void jdkELGamal(String srcMsg) {
        try {
            Security.addProvider(new BouncyCastleProvider());

            // 初始化密钥
            AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("ELGamal");
            algorithmParameterGenerator.init(256);
            AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
            DHParameterSpec dhParameterSpec = algorithmParameters.getParameterSpec(DHParameterSpec.class);

            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ELGamal");
            System.out.println(keyPairGenerator.getProvider().getInfo());
            keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
            System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));
            System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));

            // 公钥加密
            // encrypt
            Cipher cipher = Cipher.getInstance("ELGamal");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] bytes = cipher.doFinal(srcMsg.getBytes());
            // output
            String encodedMsg = Hex.encodeHexString(bytes);
            System.out.println(encodedMsg);
            System.out.println(Base64.encodeBase64String(bytes));

            // 私钥解密
            // decrypt
            cipher = Cipher.getInstance("ELGamal");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            bytes = cipher.doFinal(bytes);
            // output
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

猜你喜欢

转载自blog.csdn.net/sinat_22840937/article/details/79941624