目前,我正在更新我的x.509证书库以支持ECC。实现的大多数构建器都使用publicKey并从密钥派生算法等。在RSA中,这很简单,您可以检查密钥的算法,然后可以验证位长。但是,对于ECC,密钥是基于曲线的,曲线名称(当然)需要在证书中指定(作为OID)。
我现在正在研究的问题是找到一种方法来从java.security.interfaces.ECPublicKey或org.bouncycastle.jce.interfaces.ECPublicKey转换为曲线名称。(两个实现都完全不同…)
我能想到的一种方法是获取密钥的ECPoint并验证它在给定曲线上。这样,我可以测试所有受支持的曲线,但是这在运行时会很麻烦,如果有点重叠2条或更多条曲线,则可能容易出错。
另一种方法是获取ECCurve(bc实现)或EllipticCurve(jre模拟)并将曲线细节与支持的实现进行比较。这还涉及逐步遍历每条已知曲线。
是否有人知道仅使用jre(8/9)和bc根据曲线或publicKey详细信息查找曲线名称的更好方法。您对第一个解决方案有何感想,得到假命中的可能性有多大。
我认为我已经使用针对jre类型规范的EC5Util类找到了有效的解决方案。所有具有相同名称的双精度类实例都使它有些混乱,但是现在可以使用这些函数了。
public static final String deriveCurveName(org.bouncycastle.jce.spec.ECParameterSpec ecParameterSpec) throws GeneralSecurityException{ for (@SuppressWarnings("rawtypes") Enumeration names = ECNamedCurveTable.getNames(); names.hasMoreElements();){ final String name = (String)names.nextElement(); final X9ECParameters params = ECNamedCurveTable.getByName(name); if (params.getN().equals(ecParameterSpec.getN()) && params.getH().equals(ecParameterSpec.getH()) && params.getCurve().equals(ecParameterSpec.getCurve()) && params.getG().equals(ecParameterSpec.getG())){ return name; } } throw new GeneralSecurityException("Could not find name for curve"); } public static final String deriveCurveName(PublicKey publicKey) throws GeneralSecurityException{ if(publicKey instanceof java.security.interfaces.ECPublicKey){ final java.security.interfaces.ECPublicKey pk = (java.security.interfaces.ECPublicKey) publicKey; final ECParameterSpec params = pk.getParams(); return deriveCurveName(EC5Util.convertSpec(params, false)); } else if(publicKey instanceof org.bouncycastle.jce.interfaces.ECPublicKey){ final org.bouncycastle.jce.interfaces.ECPublicKey pk = (org.bouncycastle.jce.interfaces.ECPublicKey) publicKey; return deriveCurveName(pk.getParameters()); } else throw new IllegalArgumentException("Can only be used with instances of ECPublicKey (either jce or bc implementation)"); } public static final String deriveCurveName(PrivateKey privateKey) throws GeneralSecurityException{ if(privateKey instanceof java.security.interfaces.ECPrivateKey){ final java.security.interfaces.ECPrivateKey pk = (java.security.interfaces.ECPrivateKey) privateKey; final ECParameterSpec params = pk.getParams(); return deriveCurveName(EC5Util.convertSpec(params, false)); } else if(privateKey instanceof org.bouncycastle.jce.interfaces.ECPrivateKey){ final org.bouncycastle.jce.interfaces.ECPrivateKey pk = (org.bouncycastle.jce.interfaces.ECPrivateKey) privateKey; return deriveCurveName(pk.getParameters()); } else throw new IllegalArgumentException("Can only be used with instances of ECPrivateKey (either jce or bc implementation)"); }