Java实现非对称加密【详解】

Java实现非对称加密

  • 1. 简介
  • 2. 非对称加密算法--DH(密钥交换)
  • 3. 非对称加密算法--RSA
  • 非对称加密算法--EIGamal
  • 5. 总结
  • 6 案例
    • 6.1 案例1
    • 6.2 案例2

1. 简介

公开密钥密码学(英语:Public-key cryptography)也称非对称式密码学(英语:Asymmetric cryptography)是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;公钥用作加密,私钥则用作解密。使用公钥把明文加密后所得的密文,只能用相对应的私钥才能解密并得到原本的明文,最初用来加密的公钥不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密;不同于加密和解密都使用同一个密钥的对称加密。公钥可以公开,可任意向外发布;私钥不可以公开,必须由用户自行严格秘密保管,绝不透过任何途径向任何人提供,也不会透露给被信任的要通信的另一方。
基于公开密钥加密的特性,它还能提供数字签名的功能,使电子文件可以得到如同在纸本文件上亲笔签署的效果。公开密钥基础建设透过信任数字证书认证机构的根证书、及其使用公开密钥加密作数字签名核发的公开密钥认证,形成信任链架构,已在TLS实现并在万维网的HTTP以HTTPS、在电子邮件的SMTP以SMTPS或STARTTLS引入。
在现实世界上可作比拟的例子是,一个传统保管箱,开门和关门都是使用同一条钥匙,这是对称加密;而一个公开的邮箱,投递口是任何人都可以寄信进去的,这可视为公钥;而只有信箱主人拥有钥匙可以打开信箱,这就视为私钥。
非对称加密过程:

在这里插入图片描述
此流程图显示非对称加密过程是单向的,其中一条密钥加密后只能用相对应的另一条密钥解密。

2. 非对称加密算法–DH(密钥交换)

密钥长度默认工作模式填充方式实现方
512~1024(64倍数)1024JDK

DH加解密应用:

package com.bity.dh;
 
import org.apache.commons.codec.binary.Base64;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyAgreement;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;
 
import static java.lang.System.*;
 
/**
 * <p>Title: JdkDh</p >
 * <p>Description: DH非对称算法实现 </p >
 * <p>Company: http://www.agree.com</p >
 * <p>Project: security</p >
 *
 * @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
 * @version 1.0
 * @date 2022-04-27 19:51
 */
public class JdkDh {
    
    private static final String SRC = "I'm DH encryption algorithm";
    
    public static void main(String[] args) {
        // 解决 Unsupported secret key algorithm: DES 异常
        System.getProperties().setProperty("jdk.crypto.KeyAgreement.legacyKDF", "true");
        jdkDh();
    }
    
    private static void jdkDh() {
        try {
            // 初始化发送方密钥
            KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            senderKeyPairGenerator.initialize(512);
            KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
            // 发送方密钥,发送给接收方(可以通过文件、优盘、网络等...)
            byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();
            
            // 初始化接收方密钥,注意在实际环境中接收方和发送方肯定不会在一个函数中
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc);
            PublicKey receiverPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            DHParameterSpec dhParameterSpec = ((DHPublicKey)receiverPublicKey).getParams();
            KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            receiverKeyPairGenerator.initialize(dhParameterSpec);
            KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
            PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
            byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();
            
            // 构建密钥
            KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
            receiverKeyAgreement.init(receiverPrivateKey);
            receiverKeyAgreement.doPhase(receiverPublicKey, true);
            SecretKey receiverSecretKey = 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 senderSecretKey = senderKeyAgreement.generateSecret("DES");
            
            if (Objects.equals(receiverSecretKey, senderSecretKey)) {
                out.println("双方密钥相同");
            }
            
            // 加密
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
            byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
            out.println("jdk dh encryption is : " + Base64.encodeBase64String(result));
            
            // 解密
            cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
            result = cipher.doFinal(result);
            out.println("jdk dh decrypt is : " + new String(result));
            
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

双方密钥相同
jdk dh encryption is : Be3LeXqV/q1PDEbpH62LL129gaV5Og0Eo3GY9e00B4o=
jdk dh decrypt is : I'm DH encryption algorithm

注意:由于JDK8 update 161之后,DH的密钥长度至少为512位,但DES算法密钥不能达到这样的长度,所以运行会抛出Unsupported secret key algorithm: DES异常。解决办法有两种如下:

  1. 在代码中加如下代码:
System.getProperties().setProperty("jdk.crypto.KeyAgreement.legacyKDF", "true");
  1. 在启动的时候添加JVM变量:-Djdk.crypto.KeyAgreement.legacyKDF=true
    在这里插入图片描述
    在这里插入图片描述

3. 非对称加密算法–RSA

RSA加密算法是一种非对称加密算法,在公开密钥加密和电子商业中被广泛使用。RSA是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年一起提出的。当时他们三人都在麻省理工学院工作。RSA 就是他们三人姓氏开头字母拼在一起组成的。

对极大整数做因数分解的难度决定了 RSA 算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用 RSA 加密的信息的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的 RSA 钥匙才可能被强力方式破解。到2020年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被破解的。

RSA算法加密实现:

package com.bity.rsa;
 
import org.apache.commons.codec.binary.Base64;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import static java.lang.System.*;
 
/**
 * <p>Title: JdkRsa</p >
 * <p>Description: RSA非对称加密算法实现 </p >
 * <p>Company: http://www.agree.com</p >
 * <p>Project: security</p >
 *
 * @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
 * @version 1.0
 * @date 2022-04-27 21:38
 */
public class JdkRsa {
    
    private static final String SRC = "I'm RSA encryption algorithm";
    
    public static void main(String[] args) {
        jdkRsa();
    }
    
    /**
     * JDK-RSA算法实现
     * 
     * @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
     * @date: 2022-04-28 0:15
     */
    private static void jdkRsa() {
        try {
            // 初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            
            out.println("public key is : " + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            out.println("private key is : " + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
            
            // 私钥加密,公钥解密 -- 加密
            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(StandardCharsets.UTF_8));
            out.println("私钥加密,公钥解密 -- 加密 : " + Base64.encodeBase64String(result));
            
            // 私钥加密,公钥解密 -- 解密
            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);
            out.println("私钥加密,公钥解密 -- 解密 : " + new String(result));
    
            // 公钥加密,私钥解密 -- 加密
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] res = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
            out.println("公钥加密,私钥解密 -- 加密 : " + Base64.encodeBase64String(res));
            // 公钥加密,私钥解密 -- 解密
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            res = cipher.doFinal(res);
            out.println("公钥加密,私钥解密 -- 解密 : " + new String(res));
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

public key is : MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIfDTXqCrjGHP9tCmLujavsngP8nqSHIl/JkFN8ZmQEcn48xzSXdijEG8Ssgm3SkDWICT0cW9wf3mZ+UkVxLx90CAwEAAQ==
private key is : MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAh8NNeoKuMYc/20KYu6Nq+yeA/yepIciX8mQU3xmZARyfjzHNJd2KMQbxKyCbdKQNYgJPRxb3B/eZn5SRXEvH3QIDAQABAkASyfa5E8jj1eICiE72+QDfTXJO3cBMiqRsyWkSD0rbmlL/Qv1xDDQonWM58sIR6DOBWQZ+uXbkL1VtOuZ9sgfBAiEA9IxhRwkTYA1GVUKmgZPX+7CsfUmIZi8P/r9/C29XQZUCIQCOHtBkIOupaTLPv3A4yznEidygfbL8nrLV2Xhf6wVrKQIhAJ+RdewPDPhw0QLTIaiNWrIdXv/FWl4quUolk/VXKl1dAiASpbpkGOmy7cmr9otr+EZZIlmfeT695LjEVGd19mlcmQIhAJfua+j3/PT0+z0nPIaGDvczviyl5SxmDo79rfMNpi10
私钥加密,公钥解密 -- 加密 : AiYjJSlGlz5x86mwVW/wjieG/uJsoLEqF+xRcPLzq2HL7yIrSrE3oT4wibrvUDR6kp37eHvFaAT+/wVYCreVvg==
私钥加密,公钥解密 -- 解密 : I'm RSA encryption algorithm
公钥加密,私钥解密 -- 加密 : Io2diORtKbeTz5eOOziHrqZKzS1K19U4t3YPydhM4w2LrzW7bJK/d4DQrWTBAhg8rt28OjbGcJfqd1w8MMy4iw==
公钥加密,私钥解密 -- 解密 : I'm RSA encryption algorithm

从上面例子可以看出RSA算法是支持私钥加密、公钥解密和公钥加密、私钥解密的算法。RSA也是唯一被广泛接受并实现的非对称加密算法,从某种程度来说,RSA已经成为非对称加密算法的一个标准了。

RSA数据加密传输图示:
在这里插入图片描述

非对称加密算法–EIGamal

在密码学中,ElGamal加密算法是一个基于迪菲-赫尔曼密钥交换的非对称加密算法。它在1985年由塔希尔·盖莫尔提出。GnuPG和PGP等很多密码学系统中都应用到了ElGamal算法。
ElGamal加密算法由三部分组成:密钥生成、加密和解密。

ElGamal算法加解密应用:

package com.bity.eigamal;
 
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DHParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import static java.lang.System.out;
 
/**
 * <p>Title: BouncyCastleEiGamal</p >
 * <p>Description: ElGamal加密算法实现 </p >
 * <p>Company: http://www.agree.com</p >
 * <p>Project: security</p >
 *
 * @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
 * @version 1.0
 * @date 2022-04-28 0:38
 */
public class BouncyCastleElGamal {
    
    private static final String SRC = "I'm ElGamal encryption algorithm";
    
    public static void main(String[] args) {
        bcElGamal();
    }
    
    private static void bcElGamal() {
        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");
            keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PublicKey elGamalPublicKey = keyPair.getPublic();
            PrivateKey elGamalPrivateKey = keyPair.getPrivate();
            
            out.println("public key is : " + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
            out.println("private key is : " + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));
            
            // 公钥加密,私钥解密 -- 加密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("ElGamal");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("ElGamal");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
            
            out.println("私钥加密,公钥解密 -- 解密 : " + Base64.encodeBase64String(result));
            // 公钥加密,私钥解密 -- 解密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
            keyFactory = KeyFactory.getInstance("ElGamal");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            result = cipher.doFinal(result);
            out.println("私钥加密,公钥解密 -- 加密 : " + new String(result));
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidParameterSpecException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

 
public key is : MHYwTwYGKw4HAgEBMEUCIQCxvT1SNSrVl1/8KpvPhaE1MKiaXOHWk5SACDd39SfnHwIgQ5O8oKi9mIKhEDOCKwvYB+mozFgvmuoipw/ZDl6xCicDIwACIBh0K6bn2mtdvmiSMJj/HDlotAGOmTRFMZs+PFoIobQG
private key is : MHgCAQAwTwYGKw4HAgEBMEUCIQCxvT1SNSrVl1/8KpvPhaE1MKiaXOHWk5SACDd39SfnHwIgQ5O8oKi9mIKhEDOCKwvYB+mozFgvmuoipw/ZDl6xCicEIgIge9eM9ELM12n6bQKkj8iBtIXjvPeN5mwX9clNriqfSsA=
私钥加密,公钥解密 -- 解密 : e39h4LkKXQn1EIXdDkIxmWiB2pwgO5dZJcNfSmlXqS07SrW1VSLrx0L3RhdWm8hPLaqBZieR5quU/7oTzH/uuA==
私钥加密,公钥解密 -- 加密 : I'm ElGamal encryption algorithm

ElGamal数据加密传输图示:
在这里插入图片描述

5. 总结

对称密码是指在加密和解密时使用同一个密钥的方式,公钥密码则是指在加密和解密时使用不同密钥的方式。
对称密钥加密牵涉到密钥管理的问题,尤其是密钥交换,它需要通信双方在通信之前先透过另一个安全的渠道交换共享的密钥,才可以安全地把密文透过不安全的渠道发送;对称密钥一旦被窃,其所作的加密将即时失效;而在互联网,如果通信双方分隔异地而素未谋面,则对称加密事先所需要的“安全渠道”变得不可行;非对称加密则容许加密公钥随便散布,解密的私钥不发往任何用户,只在单方保管;如此,即使公钥在网上被截获,如果没有与其匹配的私钥,也无法解密,极为适合在互联网上使用。
另一方面,公钥解密的特性可以形成数字签名,使数据和文件受到保护并可信赖;如果公钥透过数字证书认证机构签授成为电子证书,更可作为数字身份的认证,这都是对称密钥加密无法实现的。不过,公钥加密在在计算上相当复杂,性能欠佳、远远不比对称加密;因此,在一般实际情况下,往往通过公钥加密来随机创建临时的对称秘钥,亦即对话键,然后才通过对称加密来传输大量、主体的数据。

6 案例

6.1 案例1

package com.test;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

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

        MyTest02 myTest02 = new MyTest02();
        myTest02.test1(); //生成密钥
        String jm = myTest02.test2(); //通过公钥加密
        myTest02.test3(jm); //通过私钥解密
    }

    public void test1() throws NoSuchAlgorithmException {
        // 初始化密钥
        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("public key is : " + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
        System.out.println("private key is : " + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));

    }

    public String test2() throws Exception {
        String SRC = "I'm RSA encryption algorithm";
        String pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIOz/OOCWjqI/6gssHGA/cHiJnR3hNdp230g1x7Y/aWzFc8WrQnjlX4v0PdEOphfkt8CtdzgDAlz4gMTLkLdU30CAwEAAQ==";
        byte[] pubKeyDecode = Base64.getDecoder().decode(pubKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKeyDecode);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] res = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
        System.out.println("公钥加密,私钥解密 -- 加密 : " + Base64.getEncoder().encodeToString(res));
        return Base64.getEncoder().encodeToString(res);
    }

    public void test3 (String data) throws Exception {
        String pvtKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAg7P844JaOoj/qCywcYD9weImdHeE12nbfSDXHtj9pbMVzxatCeOVfi/Q90Q6mF+S3wK13OAMCXPiAxMuQt1TfQIDAQABAkAbcnUvjMj1DfwJtlaHMRSxRUoyV34tznfZmfB7E0m5MEwfCMECzVKVtnmPpl3abbSt7UFwarvhnhhqfMM3Z9BBAiEA7ny1zoW04a/KM7VJRprOtkC3IQzjiyPl8aeoaseuvIkCIQCNX9t9K6GmSpwPLdBDtfk+Krk0qfiZaB9tEOhtG4hqVQIhAIriiaZJ63r7OtA+JPw/L16n9X4D2YewUjsXHleBDluxAiB9bkjs22NGiPfBN+KJ0NBcacd8hDl+0jTfrZqqAz2bKQIgUokJPDnwtnWVvWEwAK2wkDHkpIuvVRiG0HxNhS/ZDQA=";
        byte[] pvtDecoder = Base64.getDecoder().decode(pvtKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(pvtDecoder);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decode = Base64.getDecoder().decode(data);
        byte[] res = cipher.doFinal(decode);
        System.out.printf("公钥加密,私钥解密 -- 解密: " + new String(res));
    }

6.2 案例2

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import javax.crypto.Cipher;
public class RSAEncryptionExample {
    public static void main(String[] args) throws Exception {
        String data = "Hello, world!";
        KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        System.out.println(Base64.getEncoder().encodeToString(encryptedData));

        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedData = cipher.doFinal(encryptedData);
        System.out.println(new String(decryptedData));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/266693.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring中的上下文工具你写的可能有bug

文章目录 前言功能第一种&#xff1a;ApplicationContext第二种方式&#xff1a;ApplicationContextAware第三种&#xff1a;BeanFactoryPostProcessor 源码第一种第二种第三种 前言 本篇是针对如何写一个比较好的spring工具的一个探讨。 功能 下面三种方式&#xff0c;你觉…

第1课 配置FFmpeg+OpenCV开发环境

一、配置开发环境 1.下载FFmpegOpenCV开发所用的SDK压缩包&#xff0c;并解压到E:\SDK下&#xff0c;解压后的路径应为&#xff1a;E:\SDK\ffmpeg-sdk\58\x86\dll及E:\SDK\opencv-sdk\340\x86\dll。 2.新建VC项目&#xff0c;名称为demo1&#xff0c;项目类弄为MFC应用程序&a…

Django 中集成 CKEditor 富文本编辑器详解

概要 在 Web 应用中&#xff0c;富文本编辑器是提高用户体验的重要组件之一。CKEditor 是一款流行的、功能丰富的富文本编辑器。在 Django 项目中集成 CKEditor 不仅可以提升内容编辑的灵活性&#xff0c;还能丰富用户的互动体验。本文将详细介绍如何在 Django 中集成和配置 C…

掌握函数式组件:迈向现代化前端开发的关键步骤(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【pynput】鼠标行为追踪并模拟

文章目录 前言基本思路安装依赖包实时鼠标捕获捕获鼠标位置捕获鼠标事件记录点击内容 效果图 利用本文内容从事的任何犯法行为和开发与本人无关&#xff0c;请理性利用技术服务大家&#xff0c;创建美好和谐的社会&#xff0c;让人们生活从繁琐中变得更加具有创造性&#xff01…

【SassVue】仿网易云播放器动画

简介 仿网易云播放动画 效果图&#xff08;效果图&#xff09; 最终成品效果 动画组件 src/components/musicPlay.vue <template><div class"music-play"><div></div><div></div><div></div></div> </te…

【JAVA】分布式链路追踪技术概论

目录 1.概述 2.基于日志的实现 2.1.实现思想 2.2.sleuth 2.2.可视化 3.基于agent的实现 4.联系作者 1.概述 当采用分布式架构后&#xff0c;一次请求会在多个服务之间流转&#xff0c;组成单次调用链的服务往往都分散在不同的服务器上。这就会带来一个问题&#xff1a;…

基于Kubernetes的jenkins上线

1、基于helm 部署jenkins 要求&#xff1a;当前集群配置了storageClass&#xff0c;并已指定默认的storageClass&#xff0c;一般情况下&#xff0c;创建的storageClass即为默认类 指定默认storageClass的方式 # 如果是新创建默认类&#xff1a; apiVersion: storage.k8s.io/v1…

全方位掌握卷积神经网络:理解原理 优化实践应用

计算机视觉CV的发展 检测任务 分类与检索 超分辨率重构 医学任务 无人驾驶 整体网络架构 卷积层和激活函数&#xff08;ReLU&#xff09;的组合是网络的核心组成部分 激活函数(ReLU&#xff09; 引入非线性&#xff0c;增强网络的表达能力。 卷积层 负责特征提取 池化层…

go语言初体验1--使用go install

当安装后go语言后。 尝试编写go程序。 当使用 go install 命令&#xff0c;报错。 go: go install requires a version when current directory is not in a moduleTry go install jvmgo\ch01latest to install the latest version通过查找资料。 用命令&#xff1a; go env …

数据库开发之图形化工具以及表操作的详细解析

2.3 图形化工具 2.3.1 介绍 前面我们讲解了DDL中关于数据库操作的SQL语句&#xff0c;在我们编写这些SQL时&#xff0c;都是在命令行当中完成的。大家在练习的时候应该也感受到了&#xff0c;在命令行当中来敲这些SQL语句很不方便&#xff0c;主要的原因有以下 3 点&#xff…

Centos安装vsftpd:centos配置vsftpd,ftp报200和227错误

一、centos下载安装vsftpd&#xff08;root权限&#xff09; 1、下载安装 yum -y install vsftpd 2、vsftpd的配置文件 /etc/vsftpd.conf 3、备份原来的配置文件 sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup 4、修改配置文件如下&#xff1a;vi /etc/vsftpd.conf …

Hadoop入门学习笔记——三、使用HDFS文件系统

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 三、使用HDFS文件系统3.1. 使用命令操作HDFS文件系统3.1.…

语法分析树(先看例子再看定义)

语法分析树&#xff08;先看例子再看定义&#xff09; 先讲例子 书上讲问题&#xff0c;先讲定义&#xff0c;一顿学术操作&#xff0c;让人云里雾里&#xff0c;然后出例子。其实这样往往让人觉得看书的过程就是放弃的过程。 关于语法分析树&#xff0c;我先从上篇文章的例…

新版IDEA中Git的使用(一)

说明&#xff1a;本文介绍如何在新版IDEA中使用Git 创建项目 首先&#xff0c;在GitLab里面创建一个项目&#xff08;git_demo&#xff09;&#xff0c;克隆到桌面上。 然后在IDEA中创建一个项目&#xff0c;项目路径放在这个Git文件夹里面。 Git界面 当前分支&Commit …

python dash 写一个登陆页 4

界面 代码&#xff1a; 这里引入了dash_bootstrap_components 进行界面美化 &#xff0c;要记一些className&#xff0c;也不是原来说的不用写CSS了。 from dash import Dash, html, dcc, callback, Output, Input, State import dash_bootstrap_components as dbcapp Dash(…

使用 KVM 管理程序优化虚拟化

KVM&#xff08;基于内核的虚拟机&#xff09;是一项强大的开源虚拟化技术&#xff0c;内置于Linux 内核。它支持在单个物理主机上运行多个虚拟机 (VM)&#xff0c;这对于资源效率、服务器整合以及为不同目的创建隔离环境特别有帮助。 本文将深入介绍 KVM 管理程序&#xff0…

MySQL主从架构及读写分离实战

​​​​​​ 目录 一、实验目的与环境 二、基础环境介绍 三、搭建主从集群 1、理论基础 2、同步的原理 3、搭建主从集群 3.1 配置master主服务器 3.2 配置slave从服务 3.3 主从集群测试 3.4 集群搭建扩展&#xff1a; 3.5、GTID同步集群 4、集群扩容 5、半同步复…

Git的总体认知与具体实现

GIt概念 是一种分布式控制管理器 tips:敏捷开发 -> 先上线&#xff0c;后续开发再继续开发 集中式和分布式 集中式的版本控制系统每次在写代码时都需要从服务器中拉取一份下来&#xff0c;并且如果服务器丢失了&#xff0c;那么所有的就都丢失了&#xff0c;你本机客户端仅…

电力系统风储联合一次调频MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 简介&#xff1a; 同一电力系统在不同风电渗透率下遭受同一负荷扰动时&#xff0c;其频率变化规律所示&#xff1a; &#xff08;1&#xff09;随着电力系统中风电渗透率的不断提高&#xff0c;风电零惯性响…