密码学与密钥管理

共 19 题
📑 题目列表 19 题
#
★★★

1. Java 加密体系,JCA、JCE、JSSE 的分工

请说明 Java 加密体系中的 JCA、JCE、JSSE 各自的作用与关系?

  • JCA(框架与 Provider)
  • JCE(加密实现)
  • JSSE(SSL/TLS)

Java 加密体系由三部分组成。JCA(Java Cryptography Architecture)——加密框架与抽象层,定义 MessageDigestSignatureCipherKeyGenerator 等 API 与 Provider 机制,本身不实现算法(由 Provider 提供),提供算法选择、密钥管理(KeyStore)、证书接口。JCE(Java Cryptography Extension)——加密算法实现层,提供对称/非对称加密、密钥生成、MAC、密钥协议等实现(如 AES、RSA、HMAC),通过 CipherSecretKeyFactory 等 API 使用;JDK 自带 SunJCE Provider。JSSE(Java Secure Socket Extension)——SSL/TLS 实现,提供 SSLContextSSLSocket/SSLEngineTrustManager/KeyManagerHttpsURLConnection,用于配置 HTTPS/TLS 连接与证书验证。关系:JCA 是框架,JCE 是加密实现,JSSE 是传输安全实现,三者都基于 Provider 机制、都由标准 API 驱动。工程上:数据加密用 JCA/JCE(Cipher),密码哈希用 JCA(MessageDigest),TLS/HTTPS 用 JSSE(SSLContext)。第三方 Provider(如 BouncyCastle)可扩展 JCA/JCE 的算法。

本题考察 Java 加密体系。核心是"JCA 框架、JCE 加密实现、JSSE 传输安全"。回答应点出三者关系与用途。

#
★★★

2. 哈希算法在 Java 中的正确使用,SHA-256、SHA-3 与 MD5 废弃

请说明哈希算法在 Java 中的正确使用,包括 SHA-256、SHA-3 与 MD5 的废弃?

  • SHA-256/SHA-3 使用
  • MD5/SHA-1 废弃
  • 场景选择

哈希算法在 Java 中通过 MessageDigest.getInstance("SHA-256") 使用。正确选择:SHA-256——当前安全标准,用于完整性校验、签名、证书;SHA-3——新一代哈希(Keccak),Java 支持(SHA3-256 等),安全性高,可作为 SHA-2 的替代;MD5/SHA-1——已发现碰撞攻击,应废弃,不用于安全场景(完整性校验、签名、密码存储),仅用于非安全用途(如非安全缓存键、文件去重)。密码存储:直接哈希(SHA-256)不安全——必须用加盐慢哈希(BCrypt/Argon2/PBKDF2),因为 SHA 快速可被 GPU 爆破。正确使用:MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] d = md.digest(data); 输出二进制需编码(Hex/Base64)。场景:完整性校验与签名用 SHA-256/SHA-3;密码用慢哈希。注意:哈希是"单向"校验,不提供机密性;不同场景(完整性 vs 密码)选型不同。

本题考察哈希算法正确使用。核心是"SHA-256/SHA-3 安全、MD5/SHA-1 废弃、密码须慢哈希"。回答应点出废弃与场景。

#
★★★

3. 安全随机数生成,SecureRandom vs ThreadLocalRandom

请说明 SecureRandom 与 ThreadLocalRandom 的差异,以及安全随机数生成的使用场景?

  • SecureRandom 的安全性
  • ThreadLocalRandom 的用途
  • 密码学随机数要求

SecureRandom是密码学安全的随机数生成器(CSPRNG),基于操作系统熵源(如 /dev/urandom、Windows CryptGenRandom),输出不可预测,用于安全场景(密钥、盐、IV、Session ID、token、nonce);但生成较慢、可能阻塞(熵不足时)。ThreadLocalRandom是高性能的伪随机数(非加密安全),基于线程本地种子,速度快,用于非安全场景(随机数、测试、模拟、洗牌等),但输出可预测,绝不能用于密码学Random 是普通伪随机,同样不可用于安全。使用场景:安全敏感(密钥、盐、IV、Session ID、CSRF token、OTP)必须用 SecureRandom;性能敏感且无安全要求用 ThreadLocalRandom。Java 中 SecureRandom.getInstanceStrong() 用于强熵(可能阻塞),new SecureRandom() 默认非阻塞。注意:SecureRandom 的种子/状态不可被攻击者预测,且不应重复使用相同种子。核心区分是"密码学安全 vs 性能"。

本题考察安全随机数。核心是"SecureRandom 密码学安全用于密钥/盐/IV,ThreadLocalRandom 高性能非安全"。回答应点出使用场景。

#
★★★

4. 用户密码哈希为何必须加盐并选慢哈希(BCrypt/Argon2),与 SHA-256 直接哈希的差异

请说明用户密码哈希为何必须加盐并选慢哈希(BCrypt/Argon2),以及与 SHA-256 直接哈希的差异?

  • 加盐的作用
  • 慢哈希的作用
  • 与 SHA-256 直接哈希的差异

用户密码必须加盐 + 慢哈希。加盐:为每个用户生成随机盐,哈希结果 = 慢哈希(盐+密码),使相同密码得到不同哈希,防止彩虹表攻击与相同密码碰撞(一个哈希被破解不影响其他相同密码用户);盐随机、唯一、随哈希存储。慢哈希:BCrypt/Argon2 故意设计得慢(高成本),使暴力破解/字典破解单个密码需大量时间,显著提高攻击成本;且可调参数随硬件升级。与 SHA-256 直接哈希的差异:SHA-256 是快速哈希(GPU 每秒可哈希数十亿次)、无内置盐,相同密码哈希相同(可被彩虹表/预计算攻击破解),因此直接哈希密码极不安全。慢哈希(BCrypt/Argon2)内置盐、可调成本、抗 GPU/ASIC,是密码存储的标准。工程上:用 Spring Security 的 BCryptPasswordEncoder/Argon2PasswordEncoder,或 PasswordEncoderFactories.createDelegatingPasswordEncoder()。核心是"每次密码哈希都不同(盐)+ 计算慢(成本)"。

本题考察密码哈希。核心是"盐防彩虹表 + 慢哈希抗暴力,SHA-256 快速无盐不安全"。回答应点出差异。

#
★★

5. 对称加密(AES)在 Java 中的正确使用,GCM 模式、IV 生成

请说明 AES 对称加密在 Java 中的正确使用,包括 GCM 模式与 IV 生成?

  • AES-GCM 认证加密
  • IV 生成与存储
  • 避免 ECB/弱模式

AES 在 Java 中正确使用要点:用 GCM 模式——AES-GCM 是认证加密(AEAD),同时提供机密性与完整性(自动校验 tag),推荐使用;避免 ECB(泄漏模式信息)、避免未认证的 CBC(易被比特翻转攻击)。用法:Cipher.getInstance("AES/GCM/NoPadding")init(ENCRYPT_MODE, key, GCMParameterSpec(tagLength, iv))IV 生成——IV 必须用 SecureRandom 随机生成(GCM 中 IV 唯一性至关重要,重复 IV 会破坏确定性、泄露密钥信息),IV 长度 12 字节(96 位)推荐;IV 不保密,需随密文一起存储(通常前置在密文前),解密时取出。密钥——用 SecureRandom 生成 256 位密钥,或 KeyGenerator.getInstance("AES") 生成;密钥安全存储(KMS/Vault)。其他——tagLength 通常 128 位;加解密都要用相同 IV 与密钥。工程上封装为加密工具(加密返回 iv+ciphertext),注意避免密钥硬编码。核心是"GCM 认证加密 + 随机唯一 IV + 密钥安全"。

本题考察 AES 使用。核心是"GCM 认证加密 + IV 随机唯一且随密文存储"。回答应点出避免 ECB/CBC。

SecretKey key = ...; // 256-bit AES key
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] iv = new byte[12];
new SecureRandom().nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] ct = cipher.doFinal(plain);
// 存储: iv + ct
#
★★

6. 非对称加密(RSA/ECC)在 Java 中的应用

请说明非对称加密(RSA/ECC)在 Java 中的应用与使用方式?

  • RSA/ECC 的用途
  • 密钥生成与加密/签名
  • 混合加密

非对称加密(RSA/ECC)在 Java 中用于密钥交换、数字签名、加密小数据。用途:RSA——加密(Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"),用 OAEP 填充而非 PKCS#1 v1.5)、签名(Signature.getInstance("SHA256withRSA"));ECC——签名(SHA256withECDSA)、密钥交换(ECDH)、短密钥高性能。使用:KeyPairGenerator.getInstance("RSA"/"EC") 生成密钥对,Cipher/Signature 配合公钥/私钥;ECC 用 P-256 等曲线。混合加密——非对称加密不适合加密大数据(性能差、密文长度限制),实际用"非对称加密交换对称密钥 + 对称加密(AES-GCM)加密数据"(如 TLS 的 ECDHE + AES)。签名与加密方向相反:私钥签名/解密、公钥验证/加密。工程上:密钥用 KeyStore/PEM 存储,OAEP 填充防 Bleichenbacher 攻击,RSA 密钥 ≥2048、ECC 用 P-256。核心是"密钥交换 + 签名 + 混合加密"。

本题考察非对称加密应用。核心是"RSA/ECC 用于交换/签名/加密小数据,配混合加密"。回答应点出 OAEP 与混合加密。

#
★★

7. TLS/SSL 配置最佳实践,协议版本、证书验证、主机名验证

请说明 TLS/SSL 配置的最佳实践,包括协议版本、证书验证与主机名验证?

  • 协议版本与密码套件
  • 证书链验证
  • 主机名验证

TLS/SSL 配置最佳实践:协议版本——启用 TLS 1.2/1.3,禁用 TLS 1.0/1.1 及 SSL(有已知漏洞);配置密码套件只保留强套件(AEAD、前向保密)。证书验证——客户端必须验证服务器证书链(由受信任 CA 签名、未过期、未吊销),通过 TrustManager/SSLContext 默认信任库;自定义信任库时正确配置受信任根。主机名验证——验证证书的 SAN/CN 与连接主机名匹配,防止中间人(把 A 站证书用于 B 站);Java 中 HttpsURLConnection 默认做主机名验证,SSLParameters.setEndpointIdentificationAlgorithm("HTTPS") 启用;自定义 SSLSocket 需手动设置。其他——SecureRandom 随机源、禁默认弱密钥、定期更新证书。工程上:Java 用 SSLContext.getInstance("TLSv1.3")、配置 SSLParameters;服务端(Spring Boot)用 server.ssl 配置。核心是"强协议 + 证书链验证 + 主机名验证"。

本题考察 TLS 配置最佳实践。核心是"TLS1.2/1.3 + 证书链验证 + 主机名验证"。回答应点出 endpoint identification。

#
★★

8. 密钥存储与密钥管理,KeyStore、HSM、云 KMS 如何选择

请说明密钥存储与密钥管理,包括 KeyStore、HSM 与云 KMS 的差异与适用场景?

  • KeyStore 本地存储
  • HSM 硬件保护
  • 云 KMS 托管

密钥存储与管理方案:KeyStore(如 JKS/PKCS12)——本地文件存储密钥与证书,密码保护,适合单机/小规模,但密钥随应用存储,泄露风险高、不易集中管理;HSM(Hardware Security Module)——硬件安全模块,密钥在硬件内生成、存储、运算,密钥不出硬件,安全性最高,适合高安全/金融场景,但成本高、部署复杂;云 KMS(AWS KMS、阿里云 KMS 等)——云厂商托管密钥服务,密钥由 HSM 保护,提供加密/解密/签名/轮换 API,应用通过 API 使用(密钥不落应用),适合云环境,管理成本低、可审计、支持轮换。差异:安全级别(本地 < 云 KMS < HSM)、管理便利性、成本、适用规模。选型:普通应用用云 KMS 或 KeyStore(配合良好密钥保护);高合规/金融用 HSM 或云 KMS 的专用 HSM(如 CloudHSM);密钥集中管理、轮换、审计是趋势。工程上:密钥不硬编码、引用 KMS/Vault、定期轮换。核心是"密钥的集中、安全存储与轮换管理"。

本题考察密钥存储。核心是"KeyStore 本地、HSM 硬件、云 KMS 托管,安全与成本权衡"。回答应点出选型。

#
★★

9. 数字签名在 Java 中的应用,签名算法、证书链验证

请说明数字签名在 Java 中的应用,包括签名算法与证书链验证?

  • 签名算法与流程
  • 证书链验证
  • 签名验证

数字签名在 Java 中通过 Signature 实现,流程:私钥签名(sign())、公钥验证(verify())。签名算法——常见 SHA256withRSASHA256withECDSASHA256withDSA;选型:RSA-2048+、ECC P-256、或国密 SM2withSM3;签名前对数据哈希(算法内嵌哈希)。证书链验证——用 CertificateFactory/CertPathValidator 验证证书链(签名有效、CA 信任、未过期、未吊销、KeyUsage 匹配),KeyStore 存受信任根;TrustManager 用于 TLS 场景的链验证。应用:JWT 签名(RS256/ES256)、数据文件签名、代码签名、证书签发。验证时注意:用正确公钥(来自可信证书)、验证哈希与签名、做主机名/身份校验。工程上:Signature.getInstance("SHA256withRSA")initSign(私钥)/initVerify(公钥),私钥从 KeyStore/HSM 安全获取。核心是"私钥签名 + 公钥验证 + 证书链信任"。

本题考察数字签名应用。核心是"签名/验证流程 + 证书链验证"。回答应点出算法与信任链。

#
★★

10. Java 加密体系,JCA/JCE Provider、Cipher 的算法模式(GCM/CBC)与 IV 管理如何?

请说明 Java 加密体系的 JCA/JCE Provider、Cipher 的算法模式(GCM/CBC)与 IV 管理?

  • Provider 机制
  • GCM 与 CBC 模式
  • IV 管理与随机性

JCA 通过 Provider机制提供算法实现——Cipher.getInstance("AES/GCM/NoPadding") 时按算法名从已注册的 Provider(如 SunJCEBouncyCastle)查找实现,可 Security.addProvider 添加第三方 Provider。Cipher 模式GCM——认证加密(AEAD),加密同时生成认证 tag,完整性 + 机密性,推荐;CBC——传统加密模式,需填充(PKCS5Padding),只提供机密性,无完整性保护(易被比特翻转攻击),且需配合 MAC 或仅用于 TLS 场景;ECB——不安全,不推荐。IV 管理:IV 必须随机且唯一(GCM 中 IV 复用会破坏安全性),用 SecureRandom 生成;IV 不保密,需随密文存储(解密时使用);GCM 推荐 12 字节 IV、128 位 tag。工程上:Cipher.init(ENCRYPT_MODE, key, GCMParameterSpec(tagLen, iv)),加密输出 = IV + ciphertext。选型:数据加密用 AES-GCM,避免 CBC/ECB。核心是"Provider 选择算法 + GCM 认证加密 + IV 随机唯一"。

本题考察 JCA Provider 与 Cipher 模式。核心是"Provider 机制 + GCM 认证加密优于 CBC + IV 随机唯一"。回答应点出 IV 管理。

#
★★

11. Java 的签名与证书,JCA 数字签名、X.509 证书校验与信任链如何?

请说明 Java 的 JCA 数字签名、X.509 证书校验与信任链?

  • JCA 数字签名
  • X.509 证书校验
  • 信任链验证

JCA 数字签名通过 Signature 实现(私钥签、公钥验)。X.509 证书校验:证书包含签发者、主体、有效期、公钥、扩展(SAN、KeyUsage),校验内容——签名有效(用签发者公钥验证)、有效期未过期、未吊销(CRL/OCSP)、KeyUsage/EKU 匹配用途、主体名称匹配。信任链:证书链从目标证书经中间 CA 到根 CA,逐级验证签名,直到信任锚点(受信任根证书,预置于 KeyStore);Java 用 CertPathValidator/CertPathBuilder 构建并验证证书链,KeyStore 存受信任根,TrustManager 在 TLS 中做链验证。应用:验证服务器证书(TLS)、验证签名数据、证书签发。工程上:CertificateFactory.getInstance("X.509") 解析证书,CertPathValidator 验证链,配置受信任根;注意主机名验证(SAN)。核心是"逐级验证签名到信任锚点 + 有效期/吊销/用途校验"。

本题考察签名与证书链。核心是"X.509 校验 + 信任链逐级验证到信任锚点"。回答应点出 CertPathValidator。

#
★★

12. PBKDF2/HKDF 密钥派生函数的用途与参数选择(迭代次数/输出长度)

请说明 PBKDF2/HKDF 密钥派生函数的用途与参数选择(迭代次数/输出长度)?

  • PBKDF2 与 HKDF 的用途
  • 迭代次数与输出长度
  • 密码派生 vs 密钥扩展

PBKDF2(Password-Based Key Derivation Function 2)——从密码派生密钥,用 PRF(HMAC-SHA256)迭代,参数为迭代次数(iterations)、输出长度;用于密码哈希(配合慢哈希)或从密码派生加密密钥。HKDF(HMAC-based Key Derivation Function)——从已有密钥/熵源派生密钥(不用于密码),分 extract+expand 两步,用于密钥扩展(如从主密钥派生多个子密钥、TLS 密钥派生)。参数选择:PBKDF2 迭代次数越高越安全(抗暴力)但越慢,建议至少数十万次(如 600k,随硬件提升);盐随机(≥16 字节);输出长度按需(如 256 位)。HKDF 的 info 参数用于区分用途(域分离),salt 可选。用途:PBKDF2 用于"密码→密钥",HKDF 用于"密钥→密钥"。选型:现代密码存储更推荐 Argon2/scrypt(memory-hard),PBKDF2 用于兼容/密钥派生;HKDF 用于密钥扩展。核心是"迭代次数提升暴力破解成本、HKDF 用于密钥扩展"。

本题考察 KDF 参数。核心是"PBKDF2 密码派生、迭代次数关键、HKDF 密钥扩展"。回答应点出参数选择。

#
★★

13. RSA 的 PKCS#1 v1.5 与 OAEP 填充差异,及 ECC 曲线(P-256/X25519)选择

请说明 RSA 的 PKCS#1 v1.5 与 OAEP 填充差异,以及 ECC 曲线(P-256/X25519)的选择?

  • PKCS#1 v1.5 vs OAEP
  • ECC 曲线选择
  • 安全考量

RSA 填充PKCS#1 v1.5——传统填充,存在 Bleichenbacher 等攻击(适应性选择密文攻击),非必需场景不推荐;OAEP(Optimal Asymmetric Encryption Padding)——基于随机性的填充,提供 better 安全(RA 安全),推荐用于 RSA 加密(RSA/ECB/OAEPWithSHA-256AndMGF1Padding)。ECC 曲线选择P-256(NIST P-256)——广泛使用、兼容性好,用于签名(ECDSA)与密钥交换(ECDH);X25519——Curve25519 的 X25519 密钥交换,现代推荐(性能好、实现简单、抗侧信道),用于 TLS 1.3 的密钥交换;Ed25519 用于签名。选择:签名/加密兼容用 P-256;现代密钥交换用 X25519;避免使用弱曲线(如 secp256k1 特定场景除外)。工程上:RSA 加密用 OAEP,RSA 密钥 ≥2048;ECC 用 P-256/X25519。核心是"RSA 用 OAEP 防填充攻击、ECC 用现代曲线"。

本题考察 RSA 填充与 ECC 曲线。核心是"OAEP 优于 PKCS#1 v1.5、P-256/X25519 现代曲线"。回答应点出安全考量。

#

14. Java 安全编码规范与静态分析工具,SonarQube、SpotBugs、FindSecBugs 的使用

请说明 Java 安全编码规范与静态分析工具,包括 SonarQube、SpotBugs、FindSecBugs?

  • 安全编码规范
  • 静态分析工具
  • 安全扫描集成

Java 安全编码规范与静态分析工具用于在开发阶段发现安全缺陷。安全编码规范——遵循 OWASP 安全编码规范、CERT 安全编码标准,避免常见漏洞(SQL 注入、XSS、反序列化、硬编码密钥、弱随机数等)。静态分析工具SonarQube——综合代码质量与安全扫描平台,内置安全规则(Security Hotspots、规则更好地检测漏洞),支持 CI 集成;SpotBugs——静态字节码分析工具(FindBugs 继任者),检测 bug 与潜在缺陷;FindSecBugs——SpotBugs 的安全插件,专门检测安全漏洞(注入、XSS、硬编码密钥、不安全随机、反序列化、路径遍历等)。集成:在 CI 中运行静态分析(如 mvn sonar:sonar、SpotBugs 插件),把安全缺陷纳入质量门禁(fail 构建),结合代码评审。实践:静态分析 + 依赖扫描(SAST/SCA)+ 人工评审 + 渗透测试(DAST)组合,构建安全开发闭环。核心是"在编码阶段用工具发现并修复安全缺陷"。

本题考察静态分析工具。核心是"SonarQube/SpotBugs/FindSecBugs 在 CI 中发现安全缺陷并纳入门禁"。回答应点出工具与集成。

#

15. 密钥管理,KeyStore/JKS/PKCS12、HSM/KMS 集成与密钥轮换的工程实践如何?

请说明密钥管理的工程实践,包括 KeyStore/JKS/PKCS12、HSM/KMS 集成与密钥轮换?

  • KeyStore 管理
  • HSM/KMS 集成
  • 密钥轮换

密钥管理工程实践:KeyStore——用 PKCS12 存储密钥与证书(优于 JKS),keytool 生成/导入,密码保护;密钥不硬编码、不随代码库提交。HSM/KMS 集成——高安全场景用 HSM 或云 KMS 保管密钥,应用通过 API 调用(加密/解密/签名),密钥不出受控环境;KMS 提供集中管理、审计、自动轮换。密钥轮换——定期更换密钥(如每年/颁发策略),轮换时新旧密钥并存(按版本/kid 引用),保证旧的加密数据仍可解密(需保留旧密钥/版本),完成后清理旧密钥;KMS 支持版本化轮换。工程实践:密钥按用途分离(加密、签名、HMAC)、最小权限(KMS 权限)、密钥版本管理、审计密钥使用、备份与恢复、密钥吊销。选型:便利性用云 KMS,合规用 HSM,小规模用 KeyStore+严格保护。核心是"密钥集中安全存储 + 定期轮换 + 版本管理 + 审计"。

本题考察密钥管理工程实践。核心是"KeyStore/HSM/KMS 选型 + 密钥轮换版本管理 + 最小权限审计"。回答应点出轮换实践。

#

16. 密钥轮换与安全存储,KMS 集成、环境变量 vs 配置中心如何取舍?

请说明密钥轮换与安全存储,包括 KMS 集成以及环境变量 vs 配置中心的取舍?

  • 密钥轮换
  • KMS 集成
  • 环境变量 vs 配置中心

密钥安全存储与轮换:KMS 集成——用云 KMS/Vault 管理密钥,应用通过 API 引用,密钥不落应用,支持版本化轮换与审计。密钥轮换——定期更换密钥,新旧版本并存,旧数据可用旧版本解密,完成后清理。环境变量 vs 配置中心的取舍:环境变量——把密钥/secret 放环境变量(如 SPRING_DATASOURCE_PASSWORD),避免硬编码,但难管理、无审计、变更需重启、粒度粗;配置中心(如 Nacos/Apollo/Spring Cloud Config)——集中管理配置,支持动态刷新、版本管理、灰度,但明文 secret 存配置中心有泄露风险,应配合加密(配置中心加密策略或引用 KMS/Vault 的 secret)。取舍:两者都优于硬编码;敏感 secret 推荐用 KMS/Vault(配置中心引用其 secret 或加密),环境变量适合简单场景/云原生(K8s Secret 挂载为环境变量);配置中心适合大量配置与动态更新。最佳实践:密钥存 KMS/Vault,配置中心/环境变量只存引用或加密值;用 Spring Cloud Vault 集成。核心是"secret 不落明文、集中管理、可轮换"。

本题考察密钥轮换与存储。核心是"KMS/Vault 管理密钥、环境变量与配置中心取舍、敏感 secret 加密引用"。回答应点出取舍。

#

17. Java 安全随机数,SecureRandom 的熵源与阻塞/非阻塞模式如何?

请说明 Java 安全随机数 SecureRandom 的熵源与阻塞/非阻塞模式?

  • SecureRandom 熵源
  • 阻塞 vs 非阻塞模式
  • 使用建议

SecureRandom 使用操作系统熵源。Linux 上:/dev/urandom(非阻塞)与 /dev/random(可能阻塞,熵不足时);getInstanceStrong() 使用强熵源(可能阻塞,如 /dev/random),new SecureRandom() 默认使用非阻塞熵源(NativePRNG/SHA1PRNG)。阻塞模式getInstanceStrong() 在熵不足时阻塞等待,适合一次性生成高价值密钥(如启动时生成主密钥);非阻塞模式new SecureRandom() 不阻塞,性能好,适合一般安全随机(盐、IV、Session ID、token)。熵源:Linux 用 /dev/urandom(JDK 8+ 默认 NativePRNG),Windows 用 CryptGenRandom/BCryptGenRandom。使用建议:默认用 new SecureRandom()(非阻塞,足够安全);需要强熵(如 RSA 密钥、主密钥)用 getInstanceStrong()(注意阻塞);避免设置固定种子(不可预测);SecureRandom 是线程安全的。核心是"按场景选熵源,非阻塞默认、强熵可能阻塞"。

本题考察 SecureRandom 熵源与模式。核心是"非阻塞默认 + getInstanceStrong 强熵可能阻塞"。回答应点出使用建议。

#

18. Java 的 TLS 配置,密码套件、协议版本与证书校验的工程实践如何?

请说明 Java 的 TLS 配置工程实践,包括密码套件、协议版本与证书校验?

  • 密码套件配置
  • 协议版本
  • 证书校验

Java TLS 配置工程实践:协议版本——首选 TLS 1.3,回退 TLS 1.2,启用 SSLContext.getInstance("TLSv1.3")TLSv1.2,禁用 TLS 1.0/1.1/SSL;通过 SSLParameters 设置 protocols密码套件——只启用强套件(AEAD:AES-GCM、ChaCha20-Poly1305;前向保密:ECDHE),禁用 CBC/RC4/DES/弱 Diffie-Hellman;用 SSLParameters.setCipherSuites 或服务端配置 server.ssl.ciphers证书校验——启用证书链验证(TrustManager 默认信任库、自定义信任库配置受信任根)、主机名验证SSLParameters.setEndpointIdentificationAlgorithm("HTTPS"),校验 SAN/CN 与主机名),防止中间人;服务端配置私钥与证书(server.ssl.key-store)。其他——SecureRandom 随机源、TLS 客户端(HttpClient/HttpsURLConnection)正确配置。工程上:Spring Boot 用 server.ssl.* 配置,自定义客户端用 SSLContext/SSLParameters;定期更新证书与密码套件。核心是"强协议 + 强套件 + 证书链 + 主机名验证"。

本题考察 TLS 配置工程实践。核心是"TLS1.2/1.3 + 强密码套件 + 证书链与主机名验证"。回答应点出 SSLParameters。

#

19. 常量时间比较(MessageDigest.isEqual/constant-time)在防时序攻击中的作用

请说明常量时间比较(MessageDigest.isEqual/constant-time)在防时序攻击中的作用?

  • 时序攻击原理
  • 常量时间比较
  • Java 实现

时序攻击(Timing Attack)利用比较操作在"不同前缀相同/失败"时返回时间不同,逐字节猜测秘密(如 HMAC、密码哈希、token)。普通字符串比较(equals)或字节比较会在第一个不同字节处提前返回,攻击者可统计时间差推断出秘密的每一位。常量时间比较保证无论比较结果如何,执行时间恒定(总是比较全部字节),从而消除时间差分,防时序攻击。Java 中 MessageDigest.isEqual(byte[] a, byte[] b) 实现常量时间比较(内部对全部字节做 XOR 累积),推荐用于比较 HMAC 标签、token、密码哈希等敏感值。注意MessageDigest.isEqual 在 JDK 8 中的实现存在"长度差异"的时序问题(长度不同时提前返回),高版本修复;更严格可用 javax.crypto.MacdoFinal 比较或自定义常量时间比较(无条件累加)。工程上:比较 HMAC/签名标签、密码哈希(BCrypt.matches 内部已常量时间)、JWT 验签用常量时间比较。核心是"消除时间差分,防逐字节猜测"。

本题考察常量时间比较。核心是"时序攻击利用比较时间差,常量时间比较消除差分"。回答应点出 MessageDigest.isEqual 与注意点。