Java 7下基于JCE动态检测签名算法的技术问询
针对你在Java 7 Sun JCE环境下遇到的签名算法检测问题,我有一套可行的解决方案——毕竟Java 7确实不支持直接通过OID获取签名算法,而且你又不能引入第三方提供商,那咱们就从手动维护OID与Sun JCE支持的算法名称映射入手,这是最贴合你场景的办法。
核心思路
既然你已经能通过ASN.1解析拿到签名算法的OID,那关键就是把这些标准OID对应到Java 7 Sun JCE能识别的算法名称上——因为Sun JCE支持的签名算法对应的OID是固定且公开的,咱们可以自己做一个映射表来解决这个问题。
具体步骤
构建OID到算法名称的映射表
先整理出Java 7 Sun JCE支持的常见签名算法OID与对应名称,把它们放进一个Map里:import java.util.HashMap; import java.util.Map; public class SignatureOidMapper { private static final Map<String, String> OID_TO_ALGORITHM = new HashMap<>(); static { // RSA系列签名算法 OID_TO_ALGORITHM.put("1.2.840.113549.1.1.5", "SHA1withRSA"); OID_TO_ALGORITHM.put("1.2.840.113549.1.1.11", "SHA256withRSA"); OID_TO_ALGORITHM.put("1.2.840.113549.1.1.12", "SHA384withRSA"); OID_TO_ALGORITHM.put("1.2.840.113549.1.1.13", "SHA512withRSA"); OID_TO_ALGORITHM.put("1.2.840.113549.1.1.4", "MD5withRSA"); // DSA系列签名算法 OID_TO_ALGORITHM.put("1.2.840.10040.4.3", "SHA1withDSA"); // ECDSA系列签名算法 OID_TO_ALGORITHM.put("1.2.840.10045.4.1", "SHA1withECDSA"); OID_TO_ALGORITHM.put("1.2.840.10045.4.3.2", "SHA256withECDSA"); OID_TO_ALGORITHM.put("1.2.840.10045.4.3.3", "SHA384withECDSA"); OID_TO_ALGORITHM.put("1.2.840.10045.4.3.4", "SHA512withECDSA"); } public static String getAlgorithmByOid(String oid) { return OID_TO_ALGORITHM.get(oid); } }你可以根据实际遇到的OID,随时补充这个映射表——这些对应关系都来自标准RFC和Sun JCE的官方实现规范。
通过OID获取算法并完成验签
拿到解析后的OID后,用映射表获取算法名称,再初始化Signature对象进行验签:import java.security.PublicKey; import java.security.Signature; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.SignatureException; public class SignatureVerifier { public static boolean verifySignature(byte[] data, byte[] signatureBytes, PublicKey publicKey, String oid) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { String algorithm = SignatureOidMapper.getAlgorithmByOid(oid); if (algorithm == null) { throw new NoSuchAlgorithmException("Unsupported signature algorithm OID: " + oid); } Signature signature = Signature.getInstance(algorithm); signature.initVerify(publicKey); signature.update(data); return signature.verify(signatureBytes); } }
额外注意事项
- 如果遇到映射表中没有的OID,先确认该算法是否被Java 7 Sun JCE支持——你可以通过
Security.getProviders()获取Sun JCE提供的所有算法,或者查阅Java 7的官方文档确认。 - 要是调用系统使用了Sun JCE不支持的算法,那你可能需要和调用方协商更换为支持的算法,毕竟Java 7本身的JCE支持范围有限,且不能引入第三方库。
内容的提问来源于stack exchange,提问作者saurav
相关产品推荐
相关产品推荐

