java 非对称加密算法

慕课网学习笔记
参考:java加密算法



加密密钥分为公钥和私钥。可以使用公钥加密私钥解密,也可以使用私钥加密公钥解密。非对称加密算法主要有:DH(Diffie-Hellman)密钥交换算法、RSA(基于因子分解)、Elgamal(基于离散对数)、ECC(Elliptical Curve Cryptography,椭圆曲线加密)。

DH(密钥交换)算法

如何安全地传送密钥是对称加密算法的症结所在。密钥交换算法是通过构建本地密钥来解决对称加密算法中的密钥传递的问题的。
这里写图片描述

实现该算法的步骤和所需要的类如下:

  1. 初始化发送方密钥
    -KeyPairGenerator
    -KeyPair(密钥载体,密钥对,包括公约和私钥)
    -PublicKey
  2. 初始化接收方密钥
    -KeyFactory(可以生成公钥和私钥)
    -X509EncodedKeySpec(根据ASN.1标准进行密钥编码)
    -DHPublicKey
    -DHParameterSpec
    -KeyPairGenerator
    -PrivateKey
  3. 密钥构建
    -KeyAgreement(提供密钥一致性或密钥交换协议的功能)
    -SecretKey(生成一个分组的秘密密钥)
    -KeyFactory
    -X509EncodedKeySpec
    -PublicKey
  4. 加解密
    -Cipher(JCE框架的核心)

具体实现:

package dh;

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.Base64;

public class JavaDH {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("初始字符串:" + src);
        jdkDH();
    }

    /** JDK实现密钥交换算法 */
    public static void jdkDH() throws Exception{

        //1.初始化发送方密钥
        KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("dh");
        senderKeyPairGenerator.initialize(512);//密钥长度512
        KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
        byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();//发送方公钥(需要把这个发送给)

        //2.初始化接收方密钥
        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();
        PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();

        //3.密钥构建
        KeyAgreement receiverkeyAgreement = KeyAgreement.getInstance("dh");
        receiverkeyAgreement.init(receiverPrivateKey);
        receiverkeyAgreement.doPhase(receiverPublicKey, true);
        SecretKey receiverDesKey = receiverkeyAgreement.generateSecret("des");
        byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();

        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");
        if (Objects.equals(senderDesKey,receiverDesKey)) {
            System.out.println("双方密钥相同");
        }

        //4.加密
        Cipher cipher = Cipher.getInstance("des");
        cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("密钥交换算法加密:" + Base64.encodeBase64String(result));

        //5.解密
        cipher.init(cipher.DECRYPT_MODE, receiverDesKey);
        result = cipher.doFinal(result);
        System.out.println("密钥交换算法解密:" + new String(result));
    }
}

运行结果:
这里写图片描述

这里写图片描述

非对称加密算法——RSA

RSA是唯一被广泛接受并实现的通用算法。
这里写图片描述

在RSA算法中公钥的长度远远小于私钥的长度。以下是其java实现:

package 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.Base64;


public class JavaRSA {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

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

        System.out.println("初始字符串:" + src);
        jdkRSA();

    }

    public static void jdkRSA() throws Exception{
        //1.初始化密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(512);//密钥长度为64的整数倍,最大是65536
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        System.out.println("RSA公钥:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
        System.out.println("RSA私钥:" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));

        //2.1私钥加密,公钥解密【加密】
        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[] result = cipher.doFinal(src.getBytes());
        System.out.println("JDK RSA私钥加密:" + Base64.encodeBase64String(result));

        //2.2私钥加密,公钥解密【解密】
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        result = cipher.doFinal(result);
        System.out.println("JDK RSA公钥解密:" + new String(result));

        //3.1公钥加密,私钥解密【加密】
        x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        keyFactory = KeyFactory.getInstance("RSA");
        publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        result = cipher.doFinal(src.getBytes());
        System.out.println("JDK RSA公钥加密:" + Base64.encodeBase64String(result));

        //3.2公约加密,私钥解密【解密】
        pkcs8EncodedKeySpec =  new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
        keyFactory = KeyFactory.getInstance("RSA");
        privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        result = cipher.doFinal(result);
        System.out.println("JDK RSA私钥解密:" + new String(result));
    }

}

运行结果:
这里写图片描述

RSA有两种模式公钥加密私钥解密和私钥加密公钥解密两种模式,其序列图如下:
这里写图片描述

Elgamal算法

和RSA不同的是它只提供公钥加密,它依靠BouncyCastle实现。
这里写图片描述

这里写图片描述

package elgamal;

import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
 * 非对称加密算法——ELGamal算法
 * 对于:“Illegal key size or default parameters”异常,是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。
 * Java 7 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html,
 * 下载后得到UnlimitedJCEPolicyJDK7.zip,解压替换%JAVA_HOME%/jre/lib/security的两个文件即可
 * @author gaopengfei
 *
 */
public class JavaELGamal {

    private static String src = "object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("初始字符串:" + src);
        bouncyCastleELGamal();
    }

    /**
     * Bouncy Castle实现ELGamal,这种算法和RSA算法的区别是只能公钥加密,私钥解密
     * */
    private static void bouncyCastleELGamal() throws Exception{

        Security.addProvider(new BouncyCastleProvider());//加入对Bouncy Castle的支持

        //1.初始化发送方密钥
        AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("ELGamal");
        algorithmParameterGenerator.init(256);//初始化参数生成器
        AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();//生成算法参数
        DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);//构建参数材料
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ELGamal");//实例化密钥对生成器
        //初始化密钥对生成器
        keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //公钥和私钥
        PublicKey elGamalPublicKey = keyPair.getPublic();
        PrivateKey elGamalPrivateKey = keyPair.getPrivate();
        System.out.println("ELGamal公钥:" + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
        System.out.println("ELGamal私钥:" + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));

        //2.加密【公钥加密】
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("ELGamal");
        elGamalPublicKey = (PublicKey) keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("ELGamal","BC");
        cipher.init(Cipher.ENCRYPT_MODE, elGamalPublicKey);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("ELGamal公钥加密:" + Base64.encodeBase64String(result));

        //3.解密【私钥解密】
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
        keyFactory = KeyFactory.getInstance("ELGamal");
        elGamalPrivateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        cipher.init(Cipher.DECRYPT_MODE, elGamalPrivateKey);
        result = cipher.doFinal(result);
        System.out.println("ELGamal私钥解密:" + new String(result));

//        //加密【私钥加密】
//        pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
//        keyFactory = KeyFactory.getInstance("ELGamal");
//        elGamalPrivateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//        cipher.init(Cipher.ENCRYPT_MODE, elGamalPrivateKey);
//        result = cipher.doFinal(src.getBytes());
//        System.out.println("ELGamal私钥加密:" + Base64.encodeBase64String(result));
//        
//        //解密【公钥解密】
//        x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
//        keyFactory = KeyFactory.getInstance("ELGamal");
//        elGamalPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);
//        cipher.init(Cipher.DECRYPT_MODE, elGamalPublicKey);
//        result = cipher.doFinal(result);
//        System.out.println("ELGamal解密:" + new String(result));
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非对称加密算法Java中有多种实现,其中最常用的是RSA算法。Java提供了内置的RSA算法库,可以方便地使用公钥加密和私钥解密,或者使用私钥签名和公钥验证签名。 要在Java中使用RSA算法进行非对称加密,可以按照以下步骤进行: 1. 生成RSA密钥对:使用`KeyPairGenerator`类生成一个RSA密钥对,其中包含公钥和私钥。 2. 获取公钥和私钥:从生成的密钥对中获取公钥和私钥,分别用于加密解密。 3. 使用公钥加密:使用公钥对要加密的数据进行加密,可以使用`Cipher`类来进行加密操作。 4. 使用私钥解密:使用私钥对加密后的数据进行解密,同样可以使用`Cipher`类来进行解密操作。 以下是一个简单的示例代码,演示了如何在Java中使用RSA算法进行非对称加密: ```java import java.security.*; import javax.crypto.Cipher; public class RSAEncryptionExample { public static void main(String[] args) throws Exception { // 1. 生成RSA密钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 2. 获取公钥和私钥 PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); // 3. 使用公钥加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal("Hello, World!".getBytes()); // 4. 使用私钥解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(encryptedData); // 打印加密后和解密后的数据 System.out.println("加密后的数据:" + new String(encryptedData)); System.out.println("解密后的数据:" + new String(decryptedData)); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值