小编典典

如何从ECPublicKey查找匹配的曲线名称

java

目前,我正在更新我的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详细信息查找曲线名称的更好方法。您对第一个解决方案有何感想,得到假命中的可能性有多大。


阅读 362

收藏
2020-11-26

共1个答案

小编典典

我认为我已经使用针对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)");
}
2020-11-26