非对称加密使用举例

1. HTTPS/SSL网站安全(最常见应用)

实际场景:网上购物、网银登录

​工作原理:​

  1. 当你访问 https://开头的网站时,浏览器会请求服务器的公钥证书

  2. 浏览器验证证书的合法性(由可信的证书颁发机构签发)

  3. 使用服务器的公钥加密一个随机生成的对称会话密钥

  4. 服务器用私钥解密获得会话密钥

  5. 后续通信使用对称加密(速度更快)

java 复制代码
// 简化的HTTPS握手过程模拟
import java.security.*;
import javax.crypto.*;
import java.util.Base64;

class HttpsHandshakeSimulation {
    public static void main(String[] args) throws Exception {
        // 网站服务器生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair serverKeyPair = keyGen.generateKeyPair();
        
        // 客户端生成随机会话密钥(用于对称加密)
        KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES");
        aesKeyGen.init(256);
        SecretKey sessionKey = aesKeyGen.generateKey();
        
        System.out.println("=== HTTPS握手过程模拟 ===");
        
        // 步骤1: 客户端用服务器公钥加密会话密钥
        Cipher rsaCipher = Cipher.getInstance("RSA");
        rsaCipher.init(Cipher.ENCRYPT_MODE, serverKeyPair.getPublic());
        byte[] encryptedSessionKey = rsaCipher.doFinal(sessionKey.getEncoded());
        
        System.out.println("客户端: 使用服务器公钥加密会话密钥");
        System.out.println("加密后的会话密钥: " + 
            Base64.getEncoder().encodeToString(encryptedSessionKey).substring(0, 50) + "...");
        
        // 步骤2: 服务器用私钥解密会话密钥
        rsaCipher.init(Cipher.DECRYPT_MODE, serverKeyPair.getPrivate());
        byte[] decryptedSessionKey = rsaCipher.doFinal(encryptedSessionKey);
        
        // 重建会话密钥
        SecretKey decryptedKey = new SecretKeySpec(decryptedSessionKey, 0, decryptedSessionKey.length, "AES");
        
        System.out.println("服务器: 使用私钥解密获得会话密钥");
        System.out.println("会话密钥匹配: " + java.util.Arrays.equals(
            sessionKey.getEncoded(), decryptedKey.getEncoded()));
        
        // 步骤3: 使用会话密钥进行对称加密通信(模拟)
        String sensitiveData = "信用卡号: 1234-5678-9012-3456";
        Cipher aesCipher = Cipher.getInstance("AES");
        aesCipher.init(Cipher.ENCRYPT_MODE, sessionKey);
        byte[] encryptedData = aesCipher.doFinal(sensitiveData.getBytes());
        
        System.out.println("使用会话密钥加密敏感数据: " + sensitiveData);
        System.out.println("加密后数据长度: " + encryptedData.length + " 字节");
    }
}

2. 电子邮件加密(PGP/GPG)

实际场景:商业机密邮件、个人隐私邮件

​工作原理:​

  • 发送方使用接收方的公钥加密邮件内容

  • 只有接收方可以用自己的私钥解密

  • 数字签名确保邮件来源真实性和完整性

    // 电子邮件加密模拟
    import java.security.;
    import javax.crypto.
    ;
    import java.util.Properties;
    import javax.mail.;
    import javax.mail.internet.
    ;

    class SecureEmailExample {
    private KeyPair senderKeyPair; // 发件人密钥对(用于签名)
    private KeyPair receiverKeyPair; // 收件人密钥对(用于加密)

    复制代码
      public SecureEmailExample() throws Exception {
          // 生成发件人和收件人的密钥对
          KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
          keyGen.initialize(2048);
          senderKeyPair = keyGen.generateKeyPair();
          receiverKeyPair = keyGen.generateKeyPair();
      }
      
      public void sendEncryptedEmail(String subject, String content) throws Exception {
          System.out.println("=== 发送加密邮件 ===");
          
          // 1. 发件人用私钥对邮件内容签名
          Signature signature = Signature.getInstance("SHA256withRSA");
          signature.initSign(senderKeyPair.getPrivate());
          signature.update(content.getBytes());
          byte[] digitalSignature = signature.sign();
          
          System.out.println("📧 邮件主题: " + subject);
          System.out.println("📝 原始内容: " + content);
          System.out.println("✍️ 生成数字签名完成");
          
          // 2. 使用收件人公钥加密邮件内容
          Cipher cipher = Cipher.getInstance("RSA");
          cipher.init(Cipher.ENCRYPT_MODE, receiverKeyPair.getPublic());
          String fullContent = content + "|SIGNATURE|" + 
              Base64.getEncoder().encodeToString(digitalSignature);
          byte[] encryptedContent = cipher.doFinal(fullContent.getBytes());
          
          System.out.println("🔒 邮件内容已加密");
          System.out.println("加密后大小: " + encryptedContent.length + " 字节");
          
          // 模拟发送过程
          receiveAndDecryptEmail(encryptedContent, subject);
      }
      
      private void receiveAndDecryptEmail(byte[] encryptedContent, String subject) throws Exception {
          System.out.println("\n=== 接收并解密邮件 ===");
          
          // 1. 收件人用私钥解密
          Cipher cipher = Cipher.getInstance("RSA");
          cipher.init(Cipher.DECRYPT_MODE, receiverKeyPair.getPrivate());
          byte[] decryptedContent = cipher.doFinal(encryptedContent);
          
          String[] parts = new String(decryptedContent).split("\\|SIGNATURE\\|");
          String content = parts[0];
          byte[] receivedSignature = Base64.getDecoder().decode(parts[1]);
          
          System.out.println("📧 收到邮件主题: " + subject);
          System.out.println("📝 解密内容: " + content);
          
          // 2. 使用发件人公钥验证签名
          Signature signature = Signature.getInstance("SHA256withRSA");
          signature.initVerify(senderKeyPair.getPublic());
          signature.update(content.getBytes());
          boolean valid = signature.verify(receivedSignature);
          
          System.out.println("✅ 签名验证: " + (valid ? "通过" : "失败"));
          System.out.println("🔍 邮件确实来自声称的发送者: " + valid);
      }

    }

    // 使用示例
    class EmailDemo {
    public static void main(String[] args) throws Exception {
    SecureEmailExample email = new SecureEmailExample();
    email.sendEncryptedEmail("商业合作提案",
    "尊敬的合作伙伴,\n\n我们有一个重要的商业合作提议...\n\n机密信息: 项目预算$1,000,000");
    }
    }

3. 数字货币和区块链

实际场景:比特币交易、NFT所有权验证

​工作原理:​

  • 每个用户有公钥(作为接收地址)和私钥(控制资产)

  • 交易用私钥签名,全网用公钥验证

  • 确保只有私钥持有者能花费数字货币

    // 比特币交易签名验证模拟
    import java.security.;
    import java.util.
    ;

    class BitcoinTransactionSimulation {
    static class Transaction {
    String fromAddress; // 发送方地址(公钥哈希)
    String toAddress; // 接收方地址
    double amount; // 转账金额
    byte[] signature; // 数字签名

    复制代码
          public Transaction(String from, String to, double amount) {
              this.fromAddress = from;
              this.toAddress = to;
              this.amount = amount;
          }
          
          // 对交易内容进行签名
          public void sign(PrivateKey privateKey) throws Exception {
              String transactionData = fromAddress + toAddress + amount;
              Signature sig = Signature.getInstance("SHA256withECDSA");
              sig.initSign(privateKey);
              sig.update(transactionData.getBytes());
              this.signature = sig.sign();
          }
          
          // 验证交易签名
          public boolean verifySignature(PublicKey publicKey) throws Exception {
              if (signature == null) return false;
              
              String transactionData = fromAddress + toAddress + amount;
              Signature sig = Signature.getInstance("SHA256withECDSA");
              sig.initVerify(publicKey);
              sig.update(transactionData.getBytes());
              return sig.verify(signature);
          }
      }
      
      public static void main(String[] args) throws Exception {
          System.out.println("=== 比特币交易模拟 ===");
          
          // 生成用户密钥对(比特币使用椭圆曲线加密)
          KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
          keyGen.initialize(256);
          
          // 用户A(发送方)
          KeyPair userAKeys = keyGen.generateKeyPair();
          String userAAddress = "1A1zP1" + Base64.getEncoder()
              .encodeToString(userAKeys.getPublic().getEncoded()).substring(0, 10);
          
          // 用户B(接收方)  
          KeyPair userBKeys = keyGen.generateKeyPair();
          String userBAddress = "1B2zP2" + Base64.getEncoder()
              .encodeToString(userBKeys.getPublic().getEncoded()).substring(0, 10);
          
          // 创建交易:用户A向用户B转账0.1 BTC
          Transaction tx = new Transaction(userAAddress, userBAddress, 0.1);
          
          // 用户A用私钥签名交易
          tx.sign(userAKeys.getPrivate());
          System.out.println("💰 交易创建: " + userAAddress + " → " + userBAddress + " 金额: " + tx.amount + " BTC");
          System.out.println("✍️ 交易已签名");
          
          // 矿工验证交易签名(使用用户A的公钥)
          boolean isValid = tx.verifySignature(userAKeys.getPublic());
          System.out.println("⛏️ 矿工验证结果: " + (isValid ? "有效交易" : "无效交易"));
          
          if (isValid) {
              System.out.println("✅ 交易将被包含在下一个区块中");
          } else {
              System.out.println("❌ 交易被拒绝:签名验证失败");
          }
          
          // 模拟恶意攻击:尝试用错误的公钥验证
          KeyPair attackerKeys = keyGen.generateKeyPair();
          boolean fakeVerify = tx.verifySignature(attackerKeys.getPublic());
          System.out.println("🎭 攻击者尝试验证: " + (fakeVerify ? "意外成功" : "失败(预期结果)"));
      }

    }

4. SSH密钥认证

实际场景:远程服务器登录、自动化部署

​工作原理:​

  • 客户端生成密钥对,将公钥上传到服务器

  • 登录时客户端用私钥签名挑战信息

  • 服务器用存储的公钥验证签名

    // SSH密钥认证模拟
    import java.security.*;
    import java.util.Base64;

    class SSHAuthenticationSimulation {
    public static void main(String[] args) throws Exception {
    System.out.println("=== SSH公钥认证模拟 ===\n");

    复制代码
          // 用户生成SSH密钥对
          KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
          keyGen.initialize(2048);
          KeyPair userKeys = keyGen.generateKeyPair();
          
          // 用户将公钥上传到服务器(模拟)
          String userPublicKey = Base64.getEncoder().encodeToString(userKeys.getPublic().getEncoded());
          System.out.println("1. 用户生成SSH密钥对");
          System.out.println("2. 公钥上传到服务器: ssh-rsa " + userPublicKey.substring(0, 30) + "...");
          
          // 登录过程
          System.out.println("\n3. 用户尝试登录服务器...");
          
          // 服务器生成随机挑战
          SecureRandom random = new SecureRandom();
          byte[] challenge = new byte[32];
          random.nextBytes(challenge);
          System.out.println("4. 服务器发送挑战: " + Base64.getEncoder().encodeToString(challenge).substring(0, 20) + "...");
          
          // 用户用私钥签名挑战
          Signature sig = Signature.getInstance("SHA256withRSA");
          sig.initSign(userKeys.getPrivate());
          sig.update(challenge);
          byte[] signature = sig.sign();
          System.out.println("5. 用户用私钥签名挑战");
          
          // 服务器用存储的公钥验证签名
          sig.initVerify(userKeys.getPublic());
          sig.update(challenge);
          boolean authenticated = sig.verify(signature);
          
          System.out.println("6. 服务器验证签名: " + (authenticated ? "成功" : "失败"));
          
          if (authenticated) {
              System.out.println("✅ 认证成功!允许访问服务器");
          } else {
              System.out.println("❌ 认证失败!拒绝访问");
          }
      }

    }

5. 软件代码签名

实际场景:操作系统更新、手机APP验证

​工作原理:​

  • 开发者用私钥对软件包生成数字签名

  • 用户设备用开发者的公钥验证签名

  • 确保软件未被篡改且来源可信

    // 软件代码签名验证模拟
    import java.security.;
    import java.util.zip.
    ;

    class CodeSigningSimulation {
    static class SoftwarePackage {
    String name;
    String version;
    byte[] content;
    byte[] signature;

    复制代码
          public SoftwarePackage(String name, String version, String content) {
              this.name = name;
              this.version = version;
              this.content = content.getBytes();
          }
          
          // 开发者签名软件
          public void sign(PrivateKey privateKey) throws Exception {
              Signature sig = Signature.getInstance("SHA256withRSA");
              sig.initSign(privateKey);
              sig.update(getHash());
              this.signature = sig.sign();
          }
          
          // 验证软件签名
          public boolean verify(PublicKey publicKey) throws Exception {
              if (signature == null) return false;
              
              Signature sig = Signature.getInstance("SHA256withRSA");
              sig.initVerify(publicKey);
              sig.update(getHash());
              return sig.verify(signature);
          }
          
          // 计算软件内容哈希
          private byte[] getHash() throws Exception {
              MessageDigest digest = MessageDigest.getInstance("SHA-256");
              return digest.digest(content);
          }
      }
      
      public static void main(String[] args) throws Exception {
          System.out.println("=== 软件代码签名验证 ===\n");
          
          // 软件公司生成密钥对
          KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
          keyGen.initialize(2048);
          KeyPair companyKeys = keyGen.generateKeyPair();
          
          // 创建软件包
          SoftwarePackage app = new SoftwarePackage("MyApp", "2.1.0", 
              "public class MyApp { /* 应用程序代码 */ }");
          
          // 公司签名软件
          app.sign(companyKeys.getPrivate());
          System.out.println("1. 软件公司发布: " + app.name + " v" + app.version);
          System.out.println("2. 已用公司私钥签名");
          
          // 用户下载后验证
          System.out.println("\n3. 用户下载软件...");
          System.out.println("4. 系统验证数字签名...");
          
          boolean isValid = app.verify(companyKeys.getPublic());
          
          if (isValid) {
              System.out.println("✅ 验证成功!软件未被篡改,来源可信");
              System.out.println("🔄 允许安装和运行");
          } else {
              System.out.println("❌ 验证失败!软件可能被篡改");
              System.out.println("🚫 阻止安装,警告用户");
          }
          
          // 模拟恶意软件
          System.out.println("\n--- 恶意软件模拟 ---");
          SoftwarePackage malware = new SoftwarePackage("FakeApp", "1.0", "恶意代码");
          
          // 攻击者尝试用错误密钥验证
          KeyPair attackerKeys = keyGen.generateKeyPair();
          boolean fakeVerify = malware.verify(attackerKeys.getPublic());
          System.out.println("恶意软件验证: " + (fakeVerify ? "意外通过" : "被正确阻止"));
      }

    }

6. 智能门禁系统

实际场景:办公室门禁、酒店电子钥匙

复制代码
// 智能门锁系统模拟
import java.security.*;
import java.time.LocalDateTime;

class SmartLockSystem {
    static class DigitalKey {
        String keyId;
        PublicKey lockPublicKey;  // 门锁的公钥
        PrivateKey userPrivateKey; // 用户的私钥
        LocalDateTime expiryDate;
        
        public DigitalKey(String keyId, PublicKey lockKey, PrivateKey userKey, LocalDateTime expiry) {
            this.keyId = keyId;
            this.lockPublicKey = lockKey;
            this.userPrivateKey = userKey;
            this.expiryDate = expiry;
        }
        
        // 生成开门请求
        public byte[] generateAccessRequest() throws Exception {
            String requestData = keyId + "|" + LocalDateTime.now().toString();
            
            // 用用户私钥签名
            Signature sig = Signature.getInstance("SHA256withRSA");
            sig.initSign(userPrivateKey);
            sig.update(requestData.getBytes());
            byte[] signature = sig.sign();
            
            // 用门锁公钥加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, lockPublicKey);
            return cipher.doFinal((requestData + "|SIG|" + 
                Base64.getEncoder().encodeToString(signature)).getBytes());
        }
    }
    
    static class SmartLock {
        PrivateKey lockPrivateKey;
        PublicKey lockPublicKey;
        
        public SmartLock() throws Exception {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(2048);
            KeyPair keyPair = keyGen.generateKeyPair();
            this.lockPrivateKey = keyPair.getPrivate();
            this.lockPublicKey = keyPair.getPublic();
        }
        
        public boolean processAccessRequest(byte[] encryptedRequest, DigitalKey validKey) throws Exception {
            // 用门锁私钥解密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, lockPrivateKey);
            String decrypted = new String(cipher.doFinal(encryptedRequest));
            
            String[] parts = decrypted.split("\\|SIG\\|");
            String requestData = parts[0];
            byte[] signature = Base64.getDecoder().decode(parts[1]);
            
            String[] dataParts = requestData.split("\\|");
            String keyId = dataParts[0];
            LocalDateTime requestTime = LocalDateTime.parse(dataParts[1]);
            
            // 验证签名
            Signature sig = Signature.getInstance("SHA256withRSA");
            sig.initVerify(validKey.lockPublicKey); // 应该用用户公钥验证
            sig.update(requestData.getBytes());
            boolean validSignature = sig.verify(signature);
            
            boolean validTime = requestTime.isAfter(LocalDateTime.now().minusMinutes(5));
            boolean notExpired = validKey.expiryDate.isAfter(LocalDateTime.now());
            
            System.out.println("🔐 门锁验证:");
            System.out.println("  - 签名有效: " + validSignature);
            System.out.println("  - 请求时间有效: " + validTime);
            System.out.println("  - 密钥未过期: " + notExpired);
            
            return validSignature && validTime && notExpired;
        }
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println("=== 智能门锁系统 ===\n");
        
        SmartLock officeLock = new SmartLock();
        
        // 为员工生成数字钥匙
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair employeeKeys = keyGen.generateKeyPair();
        
        DigitalKey employeeKey = new DigitalKey("EMP001", 
            officeLock.lockPublicKey, employeeKeys.getPrivate(),
            LocalDateTime.now().plusDays(30));
        
        System.out.println("1. 员工数字钥匙已发放(有效期30天)");
        
        // 员工尝试开门
        System.out.println("\n2. 员工尝试进入办公室...");
        byte[] accessRequest = employeeKey.generateAccessRequest();
        
        boolean accessGranted = officeLock.processAccessRequest(accessRequest, employeeKey);
        
        if (accessGranted) {
            System.out.println("✅ 访问 granted!门锁打开");
        } else {
            System.out.println("❌ 访问 denied!门锁保持关闭");
        }
    }
}

总结

非对称加密在现代生活中的应用非常广泛:

应用场景 使用的非对称加密特性 实际例子
​HTTPS/SSL​ 密钥交换、身份验证 网上银行、电商网站
​电子邮件加密​ 保密性、完整性验证 商业机密通信
​数字货币​ 数字签名、所有权证明 比特币、以太坊交易
​SSH登录​ 身份认证 服务器远程管理
​代码签名​ 来源验证、完整性保护 软件更新、APP商店
​智能门禁​ 身份认证、访问控制 办公室门禁、酒店门卡

这些应用都依赖于非对称加密的核心优势:​​公钥可以公开分享,私钥必须严格保密​​,从而解决了安全通信中的密钥分发问题。

相关推荐
要做朋鱼燕3 天前
【AES加密专题】1.AES的原理详解和加密过程
运维·网络·密码学·c·加密·aes·嵌入式工具
lfq76120415 天前
C#对称加密(AES)的简单代码
安全·c#·加密·对称加密
iphone1081 个月前
视频版权保护有哪些好用的加密方案
音视频·加密·加密软件·视频加密·加密技术·视频安全·视频版权保护
金刚钻信息1 个月前
如何监控员工的电脑?7款实用的员工电脑管理软件,探索高效管理捷径!
电脑·加密·加密软件·桌面管理·文件夹加密软件·网络行为管理器
私人珍藏库1 个月前
[吾爱出品] PDF文件加密解密工作,附带源码。
windows·pdf·加密
openHiTLS密码开源社区2 个月前
【密码学基础】加密消息语法 CMS:给数字信息装个 “安全保险箱”
cms·加密·签名·验证·加密消息语法
KWMax4 个月前
RSA加密原理及推导
加密·rsa
亚林瓜子4 个月前
设置AWS EC2默认使用加密磁盘
云计算·磁盘·aws·加密
GettingReal4 个月前
Python 构建壳来启动加密的 SpringBoot Jar 包,增加反编译难度
spring boot·python·jar·加密