实验二 电子公文传输系统安全-进展2

  • 上周任务完成情况(代码链接,所写文档等)
  • 本周计划

上周任务完成情况

  • 使用国密算法SM2,在注册账号时为用户生成公私钥对
try {
    // 设置 SM2 曲线参数
    ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("sm2p256v1");
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
    keyPairGenerator.initialize(ecGenSpec, new SecureRandom());

    // 生成密钥对
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    PublicKey publicKey = keyPair.getPublic();
    // 获取桌面路径(这里假设是Windows系统,路径可能需要根据实际操作系统进行调整)
    String desktopPath = System.getProperty("user.home") + "/Desktop/";
    String fileName = number +"_sm2_private_key.pem";

    // 将私钥写入 PEM 文件
    try (JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(desktopPath + fileName))) {
        pemWriter.writeObject(keyPair.getPrivate());
    }
} catch (Exception e) {
    e.printStackTrace();
}

(生成的私钥以pem文件格式存放在桌面,公钥上传到数据库)

  • 使用国密算法SM4加密电子公文系统中的公文
try {
    // 使用 PBE(Password-Based Encryption)生成 SM4 密钥
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
    // 修改盐值和密钥长度,确保生成16字节(128位)的密钥
    KeySpec spec = new PBEKeySpec(en_key.toCharArray(), en_key.getBytes(), 65536, 128); // 128位密钥长度
    SecretKey tmp = factory.generateSecret(spec);
    sm4secretKey = new SecretKeySpec(tmp.getEncoded(), "SM4");
    // 加密文本
    encryptedContent = encryptSM4(replyContent, sm4secretKey);
    // SM3 哈希
    sm3Hash = generateSM3Hash(encryptedContent);
} catch (Exception e) {
    e.printStackTrace();
    // 处理异常
}

  • 接收方的公钥对SM4密钥加密
String sql2 = "SELECT public_key FROM user WHERE number = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql2)) {
    pstmt.setString(1, re_num);
    try (ResultSet rs = pstmt.executeQuery()) {
        if (rs.next()) {
            String publicKeyStr = rs.getString("public_key");
            byte[] publicBytes = Base64.getDecoder().decode(publicKeyStr);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            byte[] sm4KeyBytes = sm4secretKey.getEncoded();
            byte[] encryptedSM4Key = encrypt(sm4KeyBytes, publicKey);
            encryptedSM4KeyBase64 = Base64.getEncoder().encodeToString(encryptedSM4Key);
        }
    }
}
  • 接收方使用自己的私钥解密对称密钥,对称密钥解密密文
// 解密SM4密钥
byte[] encryptedSM4Key = Base64.getDecoder().decode(ened_key);
byte[] decryptedSM4KeyBytes = decrypt(encryptedSM4Key, privateKey);
SecretKey decryptedSM4Key = new SecretKeySpec(decryptedSM4KeyBytes, "SM4");
// 使用SM4解密内容
decryptedContent = decryptSM4(encryptedContent, decryptedSM4Key);
} catch (Exception e) {
e.printStackTrace();
} finally {
response.sendRedirect("show.jsp?number=" + re_number + "&decryptedContent=" + decryptedContent);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}

过程:
发送公文
查看收到的公文
查看解密后的公文内容

本周计划

1.完善相关界面
2.进一步简化改进代码