当前位置: 首页 > article >正文

《Java加密与解密的艺术》第3章java加密利器

java.security包详解

摘要 Digest

摘要类图

摘要使用示例

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;

public class MessageDigestExample {
    public static void main(String[] args) {
        String input = "Hello, World!";

        try {
            // 创建 MessageDigest 实例,指定算法为 SHA-256
            MessageDigest digest = MessageDigest.getInstance("SHA-256");

            // 将输入字符串转换为字节数组并传递给 digest
            byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));

            // 将字节数组转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            // 输出哈希值
            System.out.println("Input: " + input);
            System.out.println("SHA-256 Hash: " + hexString.toString());

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

密钥 Key

密钥类图

KeyGenerator使用示例

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class KeyGeneratorExample {
    public static void main(String[] args) {
        try {
            // 1. 获取 KeyGenerator 实例,指定算法为 AES
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");

            // 2. 初始化 KeyGenerator,指定密钥长度(例如 128 位)
            keyGen.init(128); // 也可以是 192 或 256,取决于 JCE 支持

            // 3. 生成密钥
            SecretKey secretKey = keyGen.generateKey();

            // 4. 将密钥转换为字节数组
            byte[] keyBytes = secretKey.getEncoded();

            // 5. 将字节数组转换为 Base64 编码的字符串(便于显示和存储)
            String base64Key = Base64.getEncoder().encodeToString(keyBytes);

            // 输出生成的密钥
            System.out.println("Generated AES Key (Base64): " + base64Key);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

byte[]还原秘钥Key示例

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class SecretKeyRestoreExample {
    public static void main(String[] args) {
        try {
            // 1. 假设有一个字节数组形式的密钥(例如 AES 密钥)
            String keyBase64 = "3q2+7w=="; // Base64 编码的密钥
            byte[] keyBytes = Base64.getDecoder().decode(keyBase64);

            // 2. 使用 SecretKeySpec 将字节数组还原为 SecretKey
            SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");

            // 3. 验证还原的密钥
            System.out.println("Restored SecretKey Algorithm: " + secretKey.getAlgorithm());
            System.out.println("Restored SecretKey Format: " + secretKey.getFormat());
            System.out.println("Restored SecretKey (Base64): " +
                    Base64.getEncoder().encodeToString(secretKey.getEncoded()));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

加密算法参数 AlgorithmParameters

AlgorithmParameters 是 Java 中用于管理和传递加密算法参数的类。它提供加密算法参数的不透明表示。它通常与加密算法(如 AES、DES 等)一起使用,用于存储和传递算法的初始化参数(如 IV(初始化向量)、盐值等)。

不透明表示:不可以直接访问参数域

透明表示:可以通过某个“get”来分别访问每个值

加密算法参数与byte[]相互转换示例

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AlgorithmParametersExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 AES 密钥
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(128); // 128 位密钥
            SecretKey secretKey = keyGen.generateKey();

            // 2. 初始化 AES 加密器(使用 CBC 模式,需要 IV)
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);

            // 3. 获取 AlgorithmParameters(包含 IV 等参数)
            AlgorithmParameters params = cipher.getParameters();

            // 4. 将 AlgorithmParameters 编码为字节数组(便于存储或传输)
            byte[] encodedParams = params.getEncoded();
            System.out.println("Encoded AlgorithmParameters (Base64): " +
                    Base64.getEncoder().encodeToString(encodedParams));

            // 5. 解码 AlgorithmParameters
            AlgorithmParameters decodedParams = AlgorithmParameters.getInstance("AES");
            decodedParams.init(encodedParams);

            // 6. 从 AlgorithmParameters 中提取 IV
            IvParameterSpec ivSpec = decodedParams.getParameterSpec(IvParameterSpec.class);
            System.out.println("IV (Base64): " +
                    Base64.getEncoder().encodeToString(ivSpec.getIV()));

            // 7. 使用解码后的参数初始化解密器
            Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

            System.out.println("AlgorithmParameters usage completed successfully.");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

AlgorithmParameterGenerator 使用示例

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
import java.util.Base64;

public class DESAlgorithmParameterGeneratorExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 DES 密钥
            KeyGenerator keyGen = KeyGenerator.getInstance("DES");
            SecretKey secretKey = keyGen.generateKey();

            // 2. 获取 AlgorithmParameterGenerator 实例,指定算法为 DES
            AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DES");

            // 3. 初始化 AlgorithmParameterGenerator(可以指定密钥大小,但 DES 固定为 56 位)
            paramGen.init(56); // DES 的密钥大小固定为 56 位

            // 4. 生成 AlgorithmParameters
            AlgorithmParameters params = paramGen.generateParameters();

            // 5. 将 AlgorithmParameters 转换为 IvParameterSpec(获取 IV)
            IvParameterSpec ivSpec = params.getParameterSpec(IvParameterSpec.class);

            // 6. 输出生成的 IV
            System.out.println("Generated IV (Base64): " +
                    Base64.getEncoder().encodeToString(ivSpec.getIV()));

            // 7. 使用密钥和 IV 初始化加密器
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

            // 8. 加密数据
            String plainText = "Hello, DES!";
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
            System.out.println("Encrypted Data (Base64): " +
                    Base64.getEncoder().encodeToString(encryptedBytes));

            // 9. 使用相同的密钥和 IV 初始化解密器
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

            // 10. 解密数据
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            String decryptedText = new String(decryptedBytes);
            System.out.println("Decrypted Text: " + decryptedText);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

密钥对KeyPair

KeyPairGenerator:用于生产新的秘钥对;

KeyFactory:用于转换秘钥数据为key对象

密钥对类图

KeyPairGenerator 使用示例

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class KeyPairGeneratorExample {
    public static void main(String[] args) {
        try {
            // 1. 获取 KeyPairGenerator 实例,指定算法为 RSA
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

            // 2. 初始化 KeyPairGenerator,指定密钥大小为 2048 位
            keyPairGen.initialize(2048);

            // 3. 生成密钥对
            KeyPair keyPair = keyPairGen.generateKeyPair();

            // 4. 获取公钥和私钥
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

            // 5. 将公钥和私钥转换为 Base64 编码的字符串(便于显示和存储)
            String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
            String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKeyBytes);

            // 6. 输出公钥和私钥
            System.out.println("Generated RSA Key Pair:");
            System.out.println("Public Key (Base64): " + publicKeyBase64);
            System.out.println("Private Key (Base64): " + privateKeyBase64);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

KeyFactory 使用示例

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class KeyFactoryExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 RSA 密钥对
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(2048); // 2048 位密钥
            KeyPair keyPair = keyPairGen.generateKeyPair();

            // 2. 获取公钥和私钥的编码形式
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

            // 3. 将公钥和私钥编码为 Base64 字符串(便于显示和存储)
            String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
            String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKeyBytes);

            System.out.println("Original Public Key (Base64): " + publicKeyBase64);
            System.out.println("Original Private Key (Base64): " + privateKeyBase64);

            // 4. 使用 KeyFactory 还原公钥
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            // 还原公钥
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64));
            PublicKey restoredPublicKey = keyFactory.generatePublic(publicKeySpec);

            // 还原私钥
            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64));
            PrivateKey restoredPrivateKey = keyFactory.generatePrivate(privateKeySpec);

            // 5. 验证还原的密钥
            System.out.println("Restored Public Key (Base64): " +
                    Base64.getEncoder().encodeToString(restoredPublicKey.getEncoded()));
            System.out.println("Restored Private Key (Base64): " +
                    Base64.getEncoder().encodeToString(restoredPrivateKey.getEncoded()));

            // 6. 检查还原的密钥是否与原始密钥一致
            boolean isPublicKeyEqual = keyPair.getPublic().equals(restoredPublicKey);
            boolean isPrivateKeyEqual = keyPair.getPrivate().equals(restoredPrivateKey);

            System.out.println("Is Public Key Restored Correctly? " + isPublicKeyEqual);
            System.out.println("Is Private Key Restored Correctly? " + isPrivateKeyEqual);

        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }
}

签名Signature

Signature 使用示例

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.SignatureException;

public class SignatureDemo {
    public static void main(String[] args) {
        try {
            // 生成密钥对
            KeyPair keyPair = generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            // 要签名的数据
            String data = "Hello, World!";
            byte[] dataBytes = data.getBytes();

            // 生成签名
            byte[] signatureBytes = SignatureExample.signData(dataBytes, privateKey);
            System.out.println("Signature: " + new String(signatureBytes));

            // 验证签名
            boolean isValid = SignatureExample.verifySignature(dataBytes, signatureBytes, publicKey);
            System.out.println("Signature is valid: " + isValid);

        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
            e.printStackTrace();
        }
    }
    
    // 生成密钥对
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 密钥大小为2048位
        return keyPairGenerator.generateKeyPair();
    }
    
    // 生成签名
    public static byte[] signData(byte[] data, PrivateKey privateKey) 
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }
    
    // 验证签名
    public static boolean verifySignature(byte[] data, byte[] signatureBytes, PublicKey publicKey) 
            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data);
        return signature.verify(signatureBytes);
    }
}

时间戳Timestamp

创建Timestamp示例

import java.security.Timestamp;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TimestampExample {
    public static void main(String[] args) throws Exception {
        // 1. 创建证书链
        List<X509Certificate> certList = new ArrayList<>();
        // 假设我们已经有一个 X.509 证书
        X509Certificate cert = getSampleCertificate(); // 获取示例证书
        certList.add(cert);

        // 2. 创建 CertPath
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        CertPath certPath = certFactory.generateCertPath(certList);

        // 3. 创建 Timestamp
        Date timestampDate = new Date(); // 当前时间
        Timestamp timestamp = new Timestamp(timestampDate, certPath);

        // 4. 输出 Timestamp 信息
        System.out.println("Timestamp Date: " + timestamp.getTimestamp());
        System.out.println("Signer Cert Path: " + timestamp.getSignerCertPath());
    }

    // 模拟获取一个示例证书
    private static X509Certificate getSampleCertificate() throws Exception {
        // 这里可以使用 KeyPair 和自签名证书生成逻辑
        // 以下是一个占位符,实际应用中需要从文件或密钥库加载证书
        return null;
    }
}

验证Timestamp示例

import java.security.Timestamp;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TimestampVerifier {
    public static void main(String[] args) throws Exception {
        // 1. 创建证书链
        List<X509Certificate> certList = new ArrayList<>();
        X509Certificate cert = getSampleCertificate(); // 获取示例证书
        certList.add(cert);

        // 2. 创建 CertPath
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        CertPath certPath = certFactory.generateCertPath(certList);

        // 3. 创建 Timestamp
        Date timestampDate = new Date(); // 当前时间
        Timestamp timestamp = new Timestamp(timestampDate, certPath);

        // 4. 验证证书链
        boolean isCertValid = verifyCertPath(certPath);
        System.out.println("Certificate Chain is valid: " + isCertValid);

        // 5. 验证时间戳是否在证书的有效期内
        boolean isTimestampValid = verifyTimestamp(timestamp);
        System.out.println("Timestamp is valid: " + isTimestampValid);
    }

    // 验证证书链的有效性
    private static boolean verifyCertPath(CertPath certPath) {
        // 这里可以添加证书链验证逻辑
        // 例如,检查证书是否过期,是否由受信任的 CA 签发等
        return true; // 假设证书链有效
    }

    // 验证时间戳是否在证书的有效期内
    private static boolean verifyTimestamp(Timestamp timestamp) {
        Date timestampDate = timestamp.getTimestamp();
        CertPath certPath = timestamp.getSignerCertPath();
        X509Certificate signerCert = (X509Certificate) certPath.getCertificates().get(0);

        // 检查时间戳是否在证书的有效期内
        return timestampDate.after(signerCert.getNotBefore()) &&
               timestampDate.before(signerCert.getNotAfter());
    }

    // 模拟获取一个示例证书
    private static X509Certificate getSampleCertificate() throws Exception {
        // 这里可以使用 KeyPair 和自签名证书生成逻辑
        // 以下是一个占位符,实际应用中需要从文件或密钥库加载证书
        return null;
    }
}

密钥库KeyStore

java.security.KeyStore 类用于管理密钥和证书。KeyStore 可以存储以下内容:

  • 私钥(Private Key)

  • 公钥证书(Public Key Certificate)

  • 受信任的证书(Trusted Certificate)

创建 KeyStore 并存储密钥和证书示例

import java.io.FileOutputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.security.auth.x500.X500Principal;

public class KeyStoreExample {
    public static void main(String[] args) throws Exception {
        // 1. 创建 KeyStore
        KeyStore keyStore = KeyStore.getInstance("JKS"); // JKS 是 Java 默认的 KeyStore 类型
        keyStore.load(null, null); // 初始化一个空的 KeyStore

        // 2. 生成密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 2048 位密钥
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // 3. 创建自签名证书
        X509Certificate certificate = generateSelfSignedCertificate(keyPair, "CN=Test Certificate");

        // 4. 将私钥和证书存储到 KeyStore
        char[] password = "password".toCharArray(); // KeyStore 密码
        KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password);
        KeyStore.PrivateKeyEntry privateKeyEntry = new KeyStore.PrivateKeyEntry(privateKey, new Certificate[]{certificate});
        KeyStore.Entry entry = privateKeyEntry;
        keyStore.setEntry("myPrivateKey", entry, entryPassword);

        // 5. 将受信任的证书存储到 KeyStore
        keyStore.setCertificateEntry("myTrustedCert", certificate);

        // 6. 保存 KeyStore 到文件
        try (FileOutputStream fos = new FileOutputStream("myKeystore.jks")) {
            keyStore.store(fos, password);
        }

        System.out.println("KeyStore created and saved to myKeystore.jks");
    }

    // 生成自签名证书
    private static X509Certificate generateSelfSignedCertificate(KeyPair keyPair, String dn) throws Exception {
        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        X500Principal principal = new X500Principal(dn);

        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        certGen.setSubjectDN(principal);
        certGen.setIssuerDN(principal); // 自签名
        certGen.setNotBefore(new Date());
        certGen.setNotAfter(new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000L)); // 1 年有效期
        certGen.setPublicKey(keyPair.getPublic());
        certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");

        return certGen.generateX509Certificate(keyPair.getPrivate(), "BC"); // 使用 BouncyCastle 提供程序
    }
}

从 KeyStore 加载密钥和证书示例

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;

public class KeyStoreLoader {
    public static void main(String[] args) throws Exception {
        // 1. 加载 KeyStore
        char[] password = "password".toCharArray(); // KeyStore 密码
        KeyStore keyStore = KeyStore.getInstance("JKS");
        try (FileInputStream fis = new FileInputStream("myKeystore.jks")) {
            keyStore.load(fis, password);
        }

        // 2. 获取私钥
        KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password);
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry("myPrivateKey", entryPassword);
        PrivateKey privateKey = privateKeyEntry.getPrivateKey();
        System.out.println("Private Key loaded: " + privateKey);

        // 3. 获取证书
        Certificate certificate = keyStore.getCertificate("myTrustedCert");
        System.out.println("Certificate loaded: " + certificate);
    }
}

javax.crypto 包详解

安全消息摘要Mac

Mac 类支持以下常见的 HMAC 算法:

  • HmacSHA256

  • HmacSHA512

  • HmacSHA1

  • HmacMD5

生成 HMAC 示例

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import java.util.Base64;

public class MacExample {
    public static void main(String[] args) throws Exception {
        // 1. 生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256"); // 使用 HMAC-SHA256 算法
        SecretKey secretKey = keyGen.generateKey();

        // 2. 创建 Mac 实例
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(secretKey);

        // 3. 要计算 HMAC 的消息
        String message = "Hello, World!";
        byte[] messageBytes = message.getBytes();

        // 4. 计算 HMAC
        byte[] hmacBytes = mac.doFinal(messageBytes);
        String hmacBase64 = Base64.getEncoder().encodeToString(hmacBytes);
        System.out.println("HMAC: " + hmacBase64);
    }
}

验证 HMAC 示例

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import java.util.Base64;

public class MacVerifier {
    public static void main(String[] args) throws Exception {
        // 1. 假设我们已经有一个密钥和 HMAC
        SecretKey secretKey = getSecretKey(); // 获取密钥
        String message = "Hello, World!";
        byte[] messageBytes = message.getBytes();
        String receivedHmacBase64 = "收到的 HMAC 值";

        // 2. 创建 Mac 实例
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(secretKey);

        // 3. 计算本地 HMAC
        byte[] localHmacBytes = mac.doFinal(messageBytes);
        String localHmacBase64 = Base64.getEncoder().encodeToString(localHmacBytes);

        // 4. 比较收到的 HMAC 和本地计算的 HMAC
        if (receivedHmacBase64.equals(localHmacBase64)) {
            System.out.println("HMAC 验证成功!");
        } else {
            System.out.println("HMAC 验证失败!");
        }
    }

    // 模拟获取密钥
    private static SecretKey getSecretKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
        return keyGen.generateKey();
    }
}

密钥生成器KeyGenerator 

密钥协定KeyAgreement

KeyAgreement 类支持以下常见的密钥协商算法:

  • DH(Diffie-Hellman)

  • ECDH(Elliptic Curve Diffie-Hellman)

生成密钥对示例

import javax.crypto.KeyAgreement;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class KeyAgreementExample {
    public static void main(String[] args) throws Exception {
        // 1. 生成 Alice 的密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
        keyPairGenerator.initialize(2048); // 2048 位密钥
        KeyPair aliceKeyPair = keyPairGenerator.generateKeyPair();
        PrivateKey alicePrivateKey = aliceKeyPair.getPrivate();
        PublicKey alicePublicKey = aliceKeyPair.getPublic();

        // 2. 生成 Bob 的密钥对
        KeyPair bobKeyPair = keyPairGenerator.generateKeyPair();
        PrivateKey bobPrivateKey = bobKeyPair.getPrivate();
        PublicKey bobPublicKey = bobKeyPair.getPublic();

        // 3. Alice 和 Bob 进行密钥协商
        byte[] aliceSharedSecret = generateSharedSecret(alicePrivateKey, bobPublicKey);
        byte[] bobSharedSecret = generateSharedSecret(bobPrivateKey, alicePublicKey);

        // 4. 验证双方生成的共享密钥是否相同
        System.out.println("Alice's shared secret: " + bytesToHex(aliceSharedSecret));
        System.out.println("Bob's shared secret: " + bytesToHex(bobSharedSecret));
        System.out.println("Shared secrets match: " + java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret));
    }

    // 生成共享密钥
    private static byte[] generateSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
        KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
        keyAgreement.init(privateKey);
        keyAgreement.doPhase(publicKey, true);
        return keyAgreement.generateSecret();
    }

    // 将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}

秘密密钥工厂SecretKeyFactory

KeyGenerator:用于生产新的密钥;

SecretKeyFactory:用于转换密钥数据为key对象

byte[] 还原为密钥

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

public class SecretKeyFactoryExample {
    public static void main(String[] args) {
        try {
        	KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        	SecretKey secretKey1 = keyGenerator.generateKey();
            // 1. 假设我们有一个字节数组表示的密钥
            byte[] keyBytes = secretKey1.getEncoded();

            // 2. 使用 SecretKeySpec 将字节数组转换为 SecretKey
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
            System.out.println("SecretKeySpec: " + bytesToHex(secretKeySpec.getEncoded()));

            // 3. 使用 SecretKeyFactory 将 SecretKeySpec 转换为 SecretKey
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("AES");
            KeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
            SecretKey secretKey = keyFactory.generateSecret(keySpec);
            System.out.println("SecretKey: " + bytesToHex(secretKey.getEncoded()));
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    // 将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}

加密与解密Cipher

AES 加密和解密示例

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class CipherExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 AES 密钥
            SecretKey secretKey = generateAESKey();
            System.out.println("AES Key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()));

            // 2. 生成初始化向量 (IV)
            byte[] iv = new byte[16]; // AES 块大小为 16 字节
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // 3. 要加密的数据
            String plainText = "Hello, World!";
            System.out.println("Plain Text: " + plainText);

            // 4. 加密数据
            byte[] encryptedBytes = encrypt(plainText, secretKey, ivSpec);
            String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
            System.out.println("Encrypted Text: " + encryptedText);

            // 5. 解密数据
            String decryptedText = decrypt(encryptedBytes, secretKey, ivSpec);
            System.out.println("Decrypted Text: " + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 生成 AES 密钥
    private static SecretKey generateAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 128 位密钥
        return keyGen.generateKey();
    }

    // 加密数据
    private static byte[] encrypt(String plainText, SecretKey secretKey, IvParameterSpec ivSpec) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // AES/CBC 模式
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        return cipher.doFinal(plainText.getBytes());
    }

    // 解密数据
    private static String decrypt(byte[] encryptedBytes, SecretKey secretKey, IvParameterSpec ivSpec) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }
}

RSA 加密和解密示例

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

public class CipherRSAExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 RSA 密钥对
            KeyPair keyPair = generateRSAKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            // 2. 要加密的数据
            String plainText = "Hello, RSA!";
            System.out.println("Plain Text: " + plainText);

            // 3. 加密数据
            byte[] encryptedBytes = encrypt(plainText, publicKey);
            String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
            System.out.println("Encrypted Text: " + encryptedText);

            // 4. 解密数据
            String decryptedText = decrypt(encryptedBytes, privateKey);
            System.out.println("Decrypted Text: " + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 生成 RSA 密钥对
    private static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 2048 位密钥
        return keyPairGenerator.generateKeyPair();
    }

    // 加密数据
    private static byte[] encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(plainText.getBytes());
    }

    // 解密数据
    private static String decrypt(byte[] encryptedBytes, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }
}

密封对象SealedObject

javax.crypto.SealedObject 类用于将对象加密并封装为一个密封对象。它结合了 Cipher 的加密功能和对象的序列化功能,使得可以将任何可序列化的对象加密存储或传输。SealedObject 只能加密实现了 Serializable 接口的对象。

加密和解密对象示例

import javax.crypto.Cipher;
import javax.crypto.SealedObject;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;

public class SealedObjectExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 AES 密钥
            SecretKey secretKey = generateAESKey();
            System.out.println("AES Key: " + bytesToHex(secretKey.getEncoded()));

            // 2. 创建一个可序列化的对象
            MyObject myObject = new MyObject("Hello, SealedObject!", 123);
            System.out.println("Original Object: " + myObject);

            // 3. 加密对象
            SealedObject sealedObject = encryptObject(myObject, secretKey);
            System.out.println("Sealed Object: " + sealedObject);

            // 4. 解密对象
            MyObject decryptedObject = decryptObject(sealedObject, secretKey);
            System.out.println("Decrypted Object: " + decryptedObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 生成 AES 密钥
    private static SecretKey generateAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 128 位密钥
        return keyGen.generateKey();
    }

    // 加密对象
    private static SealedObject encryptObject(Serializable object, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return new SealedObject(object, cipher);
    }

    // 解密对象
    private static MyObject decryptObject(SealedObject sealedObject, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        return (MyObject) sealedObject.getObject(cipher);
    }

    // 将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    // 定义一个可序列化的对象
    static class MyObject implements Serializable {
        private String message;
        private int number;

        public MyObject(String message, int number) {
            this.message = message;
            this.number = number;
        }

        @Override
        public String toString() {
            return "MyObject{" +
                    "message='" + message + '\'' +
                    ", number=" + number +
                    '}';
        }
    }
}

 java.security.spec包和javax.crypto.spec包详解

密要规范KeySpec

java.security.cert包详解

证书Certificate

使用 BouncyCastle 创建 X.509 证书

import org.bouncycastle.x509.X509V3CertificateGenerator;

import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CreateCertificateExample {
    public static void main(String[] args) throws Exception {
        // 1. 生成密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 2048 位密钥
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // 2. 创建 X.509 证书
        X509Certificate certificate = generateSelfSignedCertificate(keyPair, "CN=Test Certificate");

        // 3. 使用 CertificateFactory 加载证书
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        byte[] certBytes = certificate.getEncoded();
        X509Certificate loadedCertificate = (X509Certificate) certificateFactory.generateCertificate(
                new java.io.ByteArrayInputStream(certBytes));

        // 4. 输出证书信息
        System.out.println("Subject: " + loadedCertificate.getSubjectX500Principal());
        System.out.println("Issuer: " + loadedCertificate.getIssuerX500Principal());
        System.out.println("Valid From: " + loadedCertificate.getNotBefore());
        System.out.println("Valid Until: " + loadedCertificate.getNotAfter());
        System.out.println("Serial Number: " + loadedCertificate.getSerialNumber());
        System.out.println("Signature Algorithm: " + loadedCertificate.getSigAlgName());
        System.out.println("Version: " + loadedCertificate.getVersion());
    }

    // 生成自签名证书
    private static X509Certificate generateSelfSignedCertificate(KeyPair keyPair, String dn) throws Exception {
        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        X500Principal principal = new X500Principal(dn);

        // 设置证书信息
        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        certGen.setSubjectDN(principal);
        certGen.setIssuerDN(principal); // 自签名
        certGen.setNotBefore(new Date());
        certGen.setNotAfter(new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000L)); // 1 年有效期
        certGen.setPublicKey(keyPair.getPublic());
        certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");

        // 使用私钥签名证书
        return certGen.generateX509Certificate(keyPair.getPrivate(), "BC"); // 使用 BouncyCastle 提供程序
    }
}

将证书保存到文件

import java.io.FileOutputStream;
import java.security.cert.X509Certificate;

public class SaveCertificateExample {
    public static void main(String[] args) throws Exception {
        // 生成证书(参考前面的代码)
        X509Certificate certificate = CreateCertificateExample.generateSelfSignedCertificate(
                KeyPairGenerator.getInstance("RSA").generateKeyPair(), "CN=Test Certificate");

        // 将证书保存到文件
        try (FileOutputStream fos = new FileOutputStream("certificate.cer")) {
            fos.write(certificate.getEncoded());
        }

        System.out.println("Certificate saved to certificate.cer");
    }
}

使用 CertificateFactory 加载和解析 X.509 证书

import java.io.FileInputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CertificateFactoryExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 从文件加载证书
            FileInputStream fis = new FileInputStream("certificate.cer"); // 证书文件路径
            Certificate certificate = certificateFactory.generateCertificate(fis);
            fis.close();

            // 3. 将证书转换为 X509Certificate
            if (certificate instanceof X509Certificate) {
                X509Certificate x509Certificate = (X509Certificate) certificate;

                // 4. 输出证书信息
                System.out.println("Subject: " + x509Certificate.getSubjectX500Principal());
                System.out.println("Issuer: " + x509Certificate.getIssuerX500Principal());
                System.out.println("Valid From: " + x509Certificate.getNotBefore());
                System.out.println("Valid Until: " + x509Certificate.getNotAfter());
                System.out.println("Serial Number: " + x509Certificate.getSerialNumber());
                System.out.println("Signature Algorithm: " + x509Certificate.getSigAlgName());
                System.out.println("Version: " + x509Certificate.getVersion());

                // 5. 验证证书是否有效
                Date currentDate = new Date();
                if (currentDate.before(x509Certificate.getNotAfter()) && currentDate.after(x509Certificate.getNotBefore())) {
                    System.out.println("Certificate is valid.");
                } else {
                    System.out.println("Certificate is expired or not yet valid.");
                }
            } else {
                System.out.println("The certificate is not an X.509 certificate.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用 CertificateFactory 加载证书链

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;

public class CertificateChainExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 从文件加载证书链
            FileInputStream fis = new FileInputStream("certificate-chain.pem"); // 证书链文件路径
            Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(fis);
            fis.close();

            // 3. 遍历证书链
            Iterator<? extends Certificate> iterator = certificates.iterator();
            int index = 1;
            while (iterator.hasNext()) {
                Certificate certificate = iterator.next();
                if (certificate instanceof X509Certificate) {
                    X509Certificate x509Certificate = (X509Certificate) certificate;
                    System.out.println("Certificate #" + index + ":");
                    System.out.println("  Subject: " + x509Certificate.getSubjectX500Principal());
                    System.out.println("  Issuer: " + x509Certificate.getIssuerX500Principal());
                    System.out.println("  Valid From: " + x509Certificate.getNotBefore());
                    System.out.println("  Valid Until: " + x509Certificate.getNotAfter());
                    System.out.println("  Serial Number: " + x509Certificate.getSerialNumber());
                    System.out.println("  Signature Algorithm: " + x509Certificate.getSigAlgName());
                    System.out.println("  Version: " + x509Certificate.getVersion());
                    index++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

证书撤销列表CRL

CRL:证书撤销列表,

X509CRL:标明类型为X.509的CRL

X509CRLEntry:用于表示CRL中已撤销的证书

使用 X509CRL 加载和解析 CRL

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.util.Iterator;
import java.util.Set;

public class X509CRLExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 从文件加载 CRL
            FileInputStream fis = new FileInputStream("crl.pem"); // CRL 文件路径
            X509CRL crl = (X509CRL) certificateFactory.generateCRL(fis);
            fis.close();

            // 3. 输出 CRL 信息
            System.out.println("Issuer: " + crl.getIssuerX500Principal());
            System.out.println("This Update: " + crl.getThisUpdate());
            System.out.println("Next Update: " + crl.getNextUpdate());
            System.out.println("CRL Number: " + crl.getExtensionValue("2.5.29.20")); // CRL 编号扩展

            // 4. 遍历吊销的证书条目
            Set<? extends X509CRLEntry> revokedCertificates = crl.getRevokedCertificates();
            if (revokedCertificates != null) {
                Iterator<? extends X509CRLEntry> iterator = revokedCertificates.iterator();
                while (iterator.hasNext()) {
                    X509CRLEntry entry = iterator.next();
                    System.out.println("Serial Number: " + entry.getSerialNumber());
                    System.out.println("Revocation Date: " + entry.getRevocationDate());
                    System.out.println("Reason: " + entry.getRevocationReason()); // 吊销原因
                }
            } else {
                System.out.println("No revoked certificates in this CRL.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

生成 CRL(使用 BouncyCastle)

import org.bouncycastle.asn1.x509.CRLNumber;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.X509v2CRLBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;
import org.bouncycastle.cert.jcajce.JcaX509v2CRLBuilder;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.cert.X509CRL;
import java.util.Date;

public class GenerateCRLExample {
    public static void main(String[] args) throws Exception {
        // 1. 生成密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 2048 位密钥
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();

        // 2. 创建 CRL 生成器
        X509v2CRLBuilder crlBuilder = new JcaX509v2CRLBuilder(
                new org.bouncycastle.asn1.x500.X500Name("CN=Example CA, OU=Example CA Org, O=Example CA Org, L=Example CA City, ST=Example CA State, C=US"),
                new Date()
        );

        // 3. 添加 CRL 扩展
        crlBuilder.addExtension(Extension.cRLNumber, false, new CRLNumber(BigInteger.ONE));

        // 4. 添加吊销的证书条目
        crlBuilder.addCRLEntry(
                BigInteger.valueOf(1234567890L), // 吊销证书的序列号
                new Date(), // 吊销日期
                CRLReason.privilegeWithdrawn // 吊销原因
        );

        // 5. 使用私钥签名 CRL
        X509CRL crl = new JcaX509CRLConverter().getCRL(
                crlBuilder.build(new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(privateKey))
        );

        // 6. 输出 CRL 信息
        System.out.println("Issuer: " + crl.getIssuerX500Principal());
        System.out.println("This Update: " + crl.getThisUpdate());
        System.out.println("Next Update: " + crl.getNextUpdate());
        System.out.println("CRL Number: " + crl.getExtensionValue("2.5.29.20")); // CRL 编号扩展

        // 7. 保存 CRL 到文件
        try (java.io.FileOutputStream fos = new java.io.FileOutputStream("generated_crl.pem")) {
            fos.write(crl.getEncoded());
        }

        System.out.println("CRL saved to generated_crl.pem");
    }
}

证书链CertPath

 构建证书路径

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class CertPathExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 加载证书文件
            List<X509Certificate> certificates = new ArrayList<>();
            certificates.add(loadCertificate(certificateFactory, "cert1.cer")); // 终端实体证书
            certificates.add(loadCertificate(certificateFactory, "cert2.cer")); // 中间 CA 证书
            certificates.add(loadCertificate(certificateFactory, "cert3.cer")); // 根 CA 证书

            // 3. 构建 CertPath
            CertPath certPath = certificateFactory.generateCertPath(certificates);

            // 4. 输出 CertPath 信息
            System.out.println("CertPath Type: " + certPath.getType());
            System.out.println("CertPath Length: " + certPath.getCertificates().size());
            for (java.security.cert.Certificate cert : certPath.getCertificates()) {
                X509Certificate x509Cert = (X509Certificate) cert;
                System.out.println("Subject: " + x509Cert.getSubjectX500Principal());
                System.out.println("Issuer: " + x509Cert.getIssuerX500Principal());
                System.out.println("Serial Number: " + x509Cert.getSerialNumber());
                System.out.println("Valid From: " + x509Cert.getNotBefore());
                System.out.println("Valid Until: " + x509Cert.getNotAfter());
                System.out.println("-----");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 从文件加载证书
    private static X509Certificate loadCertificate(CertificateFactory certificateFactory, String filePath) throws Exception {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            return (X509Certificate) certificateFactory.generateCertificate(fis);
        }
    }
}

验证证书路径

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.*;
import java.util.ArrayList;
import java.util.List;

public class CertPathValidationExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 加载证书文件
            List<X509Certificate> certificates = new ArrayList<>();
            certificates.add(loadCertificate(certificateFactory, "cert1.cer")); // 终端实体证书
            certificates.add(loadCertificate(certificateFactory, "cert2.cer")); // 中间 CA 证书
            certificates.add(loadCertificate(certificateFactory, "cert3.cer")); // 根 CA 证书

            // 3. 构建 CertPath
            CertPath certPath = certificateFactory.generateCertPath(certificates);

            // 4. 加载受信任的根证书
            KeyStore keyStore = KeyStore.getInstance("JKS");
            try (FileInputStream fis = new FileInputStream("truststore.jks")) {
                keyStore.load(fis, "password".toCharArray()); // 信任库密码
            }

            // 5. 创建 PKIXParameters
            PKIXParameters params = new PKIXParameters(keyStore);
            params.setRevocationEnabled(false); // 禁用吊销检查(可选)

            // 6. 验证 CertPath
            CertPathValidator validator = CertPathValidator.getInstance("PKIX");
            CertPathValidatorResult result = validator.validate(certPath, params);

            System.out.println("CertPath validation succeeded: " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 从文件加载证书
    private static X509Certificate loadCertificate(CertificateFactory certificateFactory, String filePath) throws Exception {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            return (X509Certificate) certificateFactory.generateCertificate(fis);
        }
    }
}

保存 CertPath 到文件

import java.io.FileOutputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class SaveCertPathExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 加载证书文件
            List<X509Certificate> certificates = new ArrayList<>();
            certificates.add(loadCertificate(certificateFactory, "cert1.cer")); // 终端实体证书
            certificates.add(loadCertificate(certificateFactory, "cert2.cer")); // 中间 CA 证书
            certificates.add(loadCertificate(certificateFactory, "cert3.cer")); // 根 CA 证书

            // 3. 构建 CertPath
            CertPath certPath = certificateFactory.generateCertPath(certificates);

            // 4. 保存 CertPath 到文件
            try (FileOutputStream fos = new FileOutputStream("certpath.pem")) {
                fos.write(certPath.getEncoded());
            }

            System.out.println("CertPath saved to certpath.pem");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 从文件加载证书
    private static X509Certificate loadCertificate(CertificateFactory certificateFactory, String filePath) throws Exception {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            return (X509Certificate) certificateFactory.generateCertificate(fis);
        }
    }
}

文件中加载 CertPath

import java.io.FileInputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;

public class LoadCertPathExample {
    public static void main(String[] args) {
        try {
            // 1. 创建 CertificateFactory 实例
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 2. 从文件加载 CertPath
            try (FileInputStream fis = new FileInputStream("certpath.pem")) {
                CertPath certPath = certificateFactory.generateCertPath(fis);

                // 3. 输出 CertPath 信息
                System.out.println("CertPath Type: " + certPath.getType());
                System.out.println("CertPath Length: " + certPath.getCertificates().size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


http://www.kler.cn/a/568351.html

相关文章:

  • 17、什么是智能指针,C++有哪几种智能指针【高频】
  • 考研408数据结构线性表核心知识点与易错点详解(附真题示例与避坑指南)
  • 游戏引擎学习第127天
  • Java数据结构第十六期:走进二叉树的奇妙世界(五)
  • 【QT线程】子线程阻塞主线程的一次网络api请求案例
  • 自然语言处理算法工程师的技术图谱和学习路径
  • 代码随想录算法训练day66---图论系列10《Bellman_ford 队列优化算法负权回路单源有限最短路》
  • 26、IO流(只是小入门)
  • IDEAPyCharm安装ProxyAI(CodeGPT)插件连接DeepSeek-R1教程
  • Ollama 的庐山真面目
  • 【树莓派学习】树莓派3B+的安装和环境配置
  • GIT工具学习【1】:基本操作
  • 数据库Redis数据库
  • 【中等】707.设计链表
  • zookeeper-docker版
  • JVM基础概念作用类加载运行时数据区执行引擎本地方法
  • 5G学习笔记之BWP
  • 【Java基础】Java 中 的`final` 关键字
  • 【计算机网络入门】初学计算机网络(六)
  • 车载电源管理新标杆NCV8460ADR2G 在汽车电子负载开关中的应用