BouncyCastle/JDK中如何根据给定私钥获取对应首选签名算法
解答
JDK和BouncyCastle均未提供开箱即用的getPreferredSignatureAlgorithm()类型公共方法,你可以通过读取私钥自身的算法、参数信息,自行映射匹配对应安全等级的签名算法,这也是目前开源项目里签发证书时的通用实现方案。
常见密钥类型对应的推荐签名算法
- RSA密钥:2048位密钥优先匹配
SHA256WithRSAEncryption,3072/4096位及以上长度密钥可匹配SHA384WithRSAEncryption或SHA512WithRSAEncryption - ECDSA密钥:P-256曲线对应
SHA256withECDSA,P-384曲线对应SHA384withECDSA,P-521曲线对应SHA512withECDSA;国密SM2曲线单独对应SM3withSM2 - EdDSA密钥:Ed25519对应
Ed25519,Ed448对应Ed448,这类算法签名时内置哈希步骤,无需额外指定哈希算法
参考实现代码
import java.security.PrivateKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.ECPrivateKey; public String getPreferredSignatureAlgorithm(PrivateKey privateKey) { String keyAlgorithm = privateKey.getAlgorithm(); switch (keyAlgorithm) { case "RSA": RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; int keyBitLength = rsaPrivateKey.getModulus().bitLength(); if (keyBitLength >= 4096) { return "SHA512WithRSAEncryption"; } else if (keyBitLength >= 3072) { return "SHA384WithRSAEncryption"; } else { return "SHA256WithRSAEncryption"; } case "EC": ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey; int orderBitLength = ecPrivateKey.getParams().getOrder().bitLength(); // 可在此处新增曲线OID判断,识别SM2曲线返回"SM3withSM2" if (orderBitLength >= 512) { return "SHA512withECDSA"; } else if (orderBitLength >= 384) { return "SHA384withECDSA"; } else { return "SHA256withECDSA"; } case "Ed25519": return "Ed25519"; case "Ed448": return "Ed448"; default: throw new IllegalArgumentException("暂不支持的私钥类型: " + keyAlgorithm); } }
提示:你可以通过JDK的
Security.getAlgorithms("Signature")方法获取当前运行环境支持的所有签名算法名称,避免传入环境不支持的算法名导致初始化失败。
内容的提问来源于stack exchange,提问作者tsaarni
相关产品推荐
相关产品推荐

