首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 安全通訊、數位憑證與應用實踐全解析

     編輯:Java 相關知識

前言

在現代軟體開發中,資料傳輸的安全性至關重要。本文將透過詳細的說明、豐富的圖解與完整的原始碼範例,帶領讀者深入理解 Java 中如何實作安全通訊機制。內容涵蓋訊息摘要、訊息驗證碼(MAC)、數位憑證的產生與管理、程式碼簽署,以及如何利用簽署過的 Applet 突破沙箱限制,存取本地系統資源。

核心知識點

  • 程式之間如何實現安全通訊
  • 訊息摘要的原理與生成方法(MD5、SHA 等演算法)
  • 訊息驗證碼(HMAC)的運作機制與共享金鑰管理
  • 使用 keytool 建立與維護金鑰庫
  • 程式碼驗證數位憑證簽名的實作
  • 利用數位憑證為 Applet 簽名以取得系統存取權限

基礎概念:從訊息摘要到數位簽名

訊息摘要——資料的「指紋」

訊息摘要演算法(如 MD5、SHA)將任意長度的輸入資料轉換為固定長度的雜湊值。這個值唯一對應原始資料,任何微小變動都會導致截然不同的摘要,因此可用於檢測資料是否被竄改。關鍵差異在於:加密可逆,摘要不可逆。

範例:計算字串的 MD5 摘要

package com.messagedigest;
import java.security.*;

public class DigestPass {
    public static void main(String[] args) throws Exception {
        String str = "Hello,I sent to you 80 yuan.";
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes("UTF-8"));
        byte[] re = md.digest();
        
        StringBuilder result = new StringBuilder();
        for (byte b : re) {
            result.append(String.format("%02x", b));
        }
        System.out.println(result); // 輸出 32 位十六進位字串
    }
}

進階:透過串流計算大檔案摘要

使用 DigestInputStream 可邊讀取檔案邊計算摘要,並支援控制計算起始位置(如遇特定標記才開始)。

訊息驗證碼(MAC)——防篡改的進階防線

單純傳遞摘要無法防止「中間人」同時修改資料與摘要。MAC 引入雙方共享的密鑰,將摘要加密後傳遞,只有持有相同密鑰的接收方才能驗證。常見演算法為 HmacMD5、HmacSHA1。

範例:使用共享密鑰生成 HMAC

package com.mac;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;

public class MyMac {
    public static void main(String[] args) throws Exception {
        String str = "TestString";
        byte[] keyBytes = {11,105,-119,50,4,-105,16,38,-14,-111,21,-95,70,-15,76,-74,67,-88,59,-71,55,-125,104,42};
        SecretKeySpec key = new SecretKeySpec(keyBytes, "HmacSHA1");
        Mac mac = Mac.getInstance("HmacMD5");
        mac.init(key);
        mac.update(str.getBytes("UTF-8"));
        byte[] result = mac.doFinal();
        // 轉十六進位輸出...
    }
}

數位簽名與數位憑證——身份認證的基石

MAC 要求雙方預先共享密鑰,不適合開放網路環境。非對稱加密解決此問題:發送方用私鑰加密摘要(簽名),接收方用對應公鑰解密驗證。但如何確認公鑰真屬於聲稱者?數位憑證由權威 CA(憑證授權機構)簽署,綁定主體身份與公鑰,形成信任鏈。

實戰:使用 keytool 管理金鑰與憑證

建立自簽名 CA 憑證

keytool -genkey -alias MissionCA -keyalg RSA -keysize 1024 \
  -keystore abnerCALib -validity 3650 \
  -dname "CN=美森系統軟體有限公司,OU=美森系統軟體有限公司,O=美森系統軟體有限公司,L=成都市,ST=四川省,C=CN" \
  -keypass 200100 -storepass 100200

常用 keytool 指令速查

操作指令範例
列出金鑰庫所有憑證keytool -list -keystore abnerCALib
查看特定憑證詳細資訊keytool -list -v -alias MissionCA -keystore abnerCALib
匯出憑證(二進位)keytool -export -alias MissionCA -file MissionCA.cer -keystore abnerCALib
匯出憑證(Base64 可列印)keytool -export -alias MissionCA -file MissionCA.cer -keystore abnerCALib -rfc
刪除憑證條目keytool -delete -alias MissionCA -keystore abnerCALib
修改條目密碼keytool -keypasswd -alias MissionCA -keypass 200100 -new 123456 -storepass 100200 -keystore abnerCALib

程式碼實作:CA 簽署使用者憑證

核心邏輯:讀取 CA 私鑰與使用者公開憑證,重建 X509CertInfo,設定簽發者、序號、有效期、演算法(MD5withRSA),最後以 CA 私鑰簽名並寫回金鑰庫。

// 關鍵步驟節錄
X509CertImpl caCert = new X509CertImpl(caCertEncoded);
X500Name issuer = (X500Name) caCert.getSubjectX500Principal();

X509CertImpl userCert = new X509CertImpl(userCertEncoded);
X509CertInfo info = (X509CertInfo) userCert.get(Certificate.INFO);
info.set(CertificateIssuerName.DN_NAME, issuer);
info.set(CertificateValidity.NAME, new CertificateValidity(start, end));
info.set(CertificateSerialNumber.NAME, new CertificateSerialNumber(serial));
info.set(CertificateAlgorithmId.NAME, new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid));

X509CertImpl signedCert = new X509CertImpl(info);
signedCert.sign(caPrivateKey, "MD5withRSA");
// 存入金鑰庫...

應用實戰:為 Applet 簽名突破沙箱限制

步驟總覽

  1. 建立專案專用憑證 Mission_Water
  2. 用 CA(MissionCA)簽署該憑證 → Mission_Water_Signed
  3. 將 Applet 打包為 JAR:jar cvf myapplet.jar com/applet/*.class
  4. 使用 jarsigner 簽署 JAR:jarsigner -keystore abnerCALib myapplet.jar Mission_Water_Signed
  5. 編寫 HTML 網頁嵌入 Applet,並用 htmlconverter 轉換為跨瀏覽器相容格式

範例 Applet:讀取本地 C:\WINNT\system.ini

package com.applet;
import java.applet.*;
import java.awt.*;
import java.io.*;
import javax.swing.*;

public class ShowFileApplet extends JApplet {
    private TextArea ta = new TextArea(10, 80);
    private String fileName = "C:\\WINNT\\system.ini";

    public void init() {
        try { jbInit(); myInit(); } catch (Exception e) { e.printStackTrace(); }
    }
    private void myInit() {
        try (BufferedReader in = new BufferedReader(new FileReader(fileName))) {
            String line, content = "檔案內容:\n";
            while ((line = in.readLine()) != null) content += line + "\n";
            ta.setText(content);
            getContentPane().add(ta);
        } catch (IOException ex) { ex.printStackTrace(); }
    }
}

瀏覽器執行時的安全性提示

首次載入簽署 Applet 時,Java Plugin 會彈出對話框詢問用戶是否信任該憑證。選擇「總是信任」後,同憑證簽署的所有 Applet 將自動獲得權限,無需再次確認。信任記錄可在「控制台 → Java Plugin」中管理。

安全性警告對話框 Applet 成功讀取系統檔案

總結

本文完整展示了從底層密碼學原理(摘要、MAC、非對稱加密)到工具操作(keytool、jarsigner),再到程式碼實作(CA 簽署邏輯、Applet 簽名部署)的完整鏈路。掌握這些技術,即可在 Java 應用中構建可信任的安全通訊與程式碼分發機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved