Java手动实现完整的加密通信流程
字数 1441 2025-08-22 12:22:48

Java手动实现完整的加密通信流程教学文档

1. RSA加密基础

1.1 RSA算法概述

RSA是一种非对称加密算法,使用公钥加密、私钥解密。核心组成部分:

  • 公钥(e, n):用于加密明文
  • 私钥(d, n):用于解密密文
  • 模数n:两个大质数p和q的乘积

1.2 数学基础

欧拉函数

φ(n) = (p-1)*(q-1)
如果n是质数,则φ(n) = n-1

欧拉定理

x^φ(n) ≡ 1 mod n

扩展欧几里得算法

用于计算两个整数的最大公约数(GCD)并找到整数解x和y,使得:
ax + by = gcd(a,b)

在RSA中用于求解私钥d,满足:
d × e ≡ 1 mod φ(n)

1.3 RSA密钥生成步骤

  1. 选择两个大质数p和q
  2. 计算n = p × q
  3. 计算φ(n) = (p-1)(q-1)
  4. 选择公钥指数e(通常为65537)
  5. 使用扩展欧几里得算法计算私钥d
  6. 公钥为(e, n),私钥为(d, n)

1.4 RSA明文长度限制

RSA加密的明文长度受限于模数n的字节长度:

  • 2048位密钥(256字节):
    • PKCS#1填充:最大明文245字节
    • OAEP填充:最大明文214字节

2. RSA实现代码

2.1 质数生成

public static BigInteger getPrime(int bitLength) {
    BigInteger p;
    while (!(p = BigInteger.probablePrime(bitLength, random)).isProbablePrime(100)) {
        continue;
    }
    return p;
}

2.2 密钥生成

public static BigInteger[] genRsaKey() {
    BigInteger p, q, n, φ, d, e = BigInteger.valueOf(65537);
    p = getPrime(200);
    q = getPrime(200);
    n = p.multiply(q);
    φ = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
    d = extGcd(e, φ)[0];
    BigInteger[] result = new BigInteger[]{n, e, d};
    if (d.compareTo(BigInteger.ONE) < 0 || !p.gcd(q).equals(BigInteger.ONE)) {
        return genRsaKey();
    }
    return result;
}

2.3 扩展欧几里得算法

public static BigInteger[] extGcd(BigInteger a, BigInteger b) {
    BigInteger[] result = null;
    if (b.equals(BigInteger.ZERO)) {
        result = new BigInteger[]{BigInteger.ONE, BigInteger.ZERO};
        return result;
    }
    result = extGcd(b, a.mod(b));
    BigInteger x = result[1];
    BigInteger y = result[0].subtract(a.divide(b).multiply(x));
    result = new BigInteger[]{x, y};
    return result;
}

2.4 RSA加密/解密

// RSA加密
public static byte[] rsaEncrype(byte[] m, BigInteger n, BigInteger e) {
    if (e == null) {
        e = BigInteger.valueOf(65537);
    }
    return new BigInteger(m).modPow(e, n).toByteArray();
}

// RSA解密
public static byte[] rsaDecrype(byte[] c, BigInteger n, BigInteger d) {
    return new BigInteger(c).modPow(d, n).toByteArray();
}

3. AES对称加密

3.1 AES概述

AES是一种对称加密算法,使用相同的密钥进行加密和解密。通常与RSA结合使用:

  • RSA用于安全分发AES密钥
  • AES用于实际通信内容加密

3.2 加密模式和填充方式

常见加密模式

  • ECB:最简单的模式,每个块独立加密
  • CBC:前一个密文块与当前块异或后再加密
  • CFB:类似于CBC,更适合流加密
  • OFB:加密器的输出作为下一个块的输入
  • GCM:支持认证的加密模式,确保数据完整性

常见填充方式

  • PKCS5Padding:缺少的字节填充为与块大小相同的数值
  • ISO10126Padding:随机填充,最后一个字节指明填充字节数
  • NoPadding:不使用填充,需自行确保数据是正确大小

3.3 AES实现代码

密钥和IV生成

// 随机生成16字节的IV
private static byte[] generateIV() {
    byte[] iv = new byte[16]; // AES的IV是16字节
    random.nextBytes(iv);
    return iv;
}

// 填充或截断字符串以使其为16/32字节
private static String padTo16Bytes(String input) {
    StringBuilder paddedInput = new StringBuilder(input);
    int padding_le = 16;
    if (input.length()>=16 && input.length()<=32 ) {
        padding_le =32;
    }
    else if(input.length()>32)
        return input.substring(0,32);
    while (paddedInput.length() < padding_le) {
        paddedInput.append((char)(random.nextInt(94)+32));
    }
    return paddedInput.toString();
}

AES加密/解密

private static final String aesMode = "AES/OFB/ISO10126Padding";

public static byte[] aesEncrypt(byte[] s, String k, byte[] iv) {
    try {
        Cipher c = Cipher.getInstance(aesMode);
        c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k.getBytes(), "AES"), new IvParameterSpec(iv));
        return c.doFinal(s);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

public static byte[] aesDecrypt(byte[] s, String k, byte[] iv) {
    try {
        Cipher c = Cipher.getInstance(aesMode);
        c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(k.getBytes(), "AES"), new IvParameterSpec(iv));
        return c.doFinal(s);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

4. 完整加密通信流程

4.1 通信流程设计

  1. 密钥交换阶段

    • 服务器生成RSA密钥对
    • 客户端获取服务器公钥(e, n)
    • 客户端生成随机AES密钥
    • 客户端用RSA公钥加密AES密钥并发送给服务器
    • 服务器用RSA私钥解密获取AES密钥
  2. 加密通信阶段

    • 双方使用协商好的AES密钥进行对称加密通信
    • 每次通信生成随机IV,与密文一起传输

4.2 优势分析

  • 避免了AES密钥明文传输的风险
  • 结合了RSA的安全密钥分发和AES的高效加密
  • 在流量中无法直接获取私钥,提高了安全性
  • 适用于后门与客户端的加密通信场景

5. 实际应用示例

5.1 密钥生成与分发

// 生成RSA密钥
BigInteger[] keys = genRsaKey();
BigInteger n = keys[0];
BigInteger privateKey = keys[2];

// 生成并加密AES密钥
String aesKey = "";
aesKey = padTo16Bytes(aesKey);
byte[] encryptedKey = rsaEncrype(aesKey.getBytes(), n, e);

// 解密AES密钥
byte[] decryptedKey = rsaDecrype(encryptedKey, n, privateKey);

5.2 加密通信

// 准备消息
String message = "test shellcode \\xfc\\xe8\\x89\\x00..........";
byte[] iv = generateIV();

// 加密
byte[] ciphertext = aesEncrypt(message.getBytes(), aesKey, iv);

// 解密
byte[] plaintext = aesDecrypt(ciphertext, aesKey, iv);

6. 安全注意事项

  1. RSA密钥长度应至少2048位
  2. AES密钥应足够随机且长度适当(128/192/256位)
  3. 每次加密应使用不同的IV
  4. 避免密钥硬编码
  5. 实现完整的错误处理和异常管理
  6. 考虑前向安全性设计

7. 总结

本文详细介绍了如何使用Java手动实现完整的加密通信流程,包括:

  1. RSA非对称加密的原理和实现
  2. AES对称加密的原理和实现
  3. 两种加密方式的结合使用
  4. 完整的密钥交换和加密通信流程
  5. 实际应用示例和安全注意事项

这种加密通信流程可以有效保护通信内容的安全,避免了密钥明文传输的风险,适用于各种需要安全通信的场景。

Java手动实现完整的加密通信流程教学文档 1. RSA加密基础 1.1 RSA算法概述 RSA是一种非对称加密算法,使用公钥加密、私钥解密。核心组成部分: 公钥(e, n):用于加密明文 私钥(d, n):用于解密密文 模数n:两个大质数p和q的乘积 1.2 数学基础 欧拉函数 φ(n) = (p-1)* (q-1) 如果n是质数,则φ(n) = n-1 欧拉定理 x^φ(n) ≡ 1 mod n 扩展欧几里得算法 用于计算两个整数的最大公约数(GCD)并找到整数解x和y,使得: ax + by = gcd(a,b) 在RSA中用于求解私钥d,满足: d × e ≡ 1 mod φ(n) 1.3 RSA密钥生成步骤 选择两个大质数p和q 计算n = p × q 计算φ(n) = (p-1)(q-1) 选择公钥指数e(通常为65537) 使用扩展欧几里得算法计算私钥d 公钥为(e, n),私钥为(d, n) 1.4 RSA明文长度限制 RSA加密的明文长度受限于模数n的字节长度: 2048位密钥(256字节): PKCS#1填充:最大明文245字节 OAEP填充:最大明文214字节 2. RSA实现代码 2.1 质数生成 2.2 密钥生成 2.3 扩展欧几里得算法 2.4 RSA加密/解密 3. AES对称加密 3.1 AES概述 AES是一种对称加密算法,使用相同的密钥进行加密和解密。通常与RSA结合使用: RSA用于安全分发AES密钥 AES用于实际通信内容加密 3.2 加密模式和填充方式 常见加密模式 ECB:最简单的模式,每个块独立加密 CBC:前一个密文块与当前块异或后再加密 CFB:类似于CBC,更适合流加密 OFB:加密器的输出作为下一个块的输入 GCM:支持认证的加密模式,确保数据完整性 常见填充方式 PKCS5Padding:缺少的字节填充为与块大小相同的数值 ISO10126Padding:随机填充,最后一个字节指明填充字节数 NoPadding:不使用填充,需自行确保数据是正确大小 3.3 AES实现代码 密钥和IV生成 AES加密/解密 4. 完整加密通信流程 4.1 通信流程设计 密钥交换阶段 : 服务器生成RSA密钥对 客户端获取服务器公钥(e, n) 客户端生成随机AES密钥 客户端用RSA公钥加密AES密钥并发送给服务器 服务器用RSA私钥解密获取AES密钥 加密通信阶段 : 双方使用协商好的AES密钥进行对称加密通信 每次通信生成随机IV,与密文一起传输 4.2 优势分析 避免了AES密钥明文传输的风险 结合了RSA的安全密钥分发和AES的高效加密 在流量中无法直接获取私钥,提高了安全性 适用于后门与客户端的加密通信场景 5. 实际应用示例 5.1 密钥生成与分发 5.2 加密通信 6. 安全注意事项 RSA密钥长度应至少2048位 AES密钥应足够随机且长度适当(128/192/256位) 每次加密应使用不同的IV 避免密钥硬编码 实现完整的错误处理和异常管理 考虑前向安全性设计 7. 总结 本文详细介绍了如何使用Java手动实现完整的加密通信流程,包括: RSA非对称加密的原理和实现 AES对称加密的原理和实现 两种加密方式的结合使用 完整的密钥交换和加密通信流程 实际应用示例和安全注意事项 这种加密通信流程可以有效保护通信内容的安全,避免了密钥明文传输的风险,适用于各种需要安全通信的场景。