Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用具有Java安全性的openssh公钥(ecdsa-sha2-nistp256)_Java_Openssh_Jce_Elliptic Curve_Ecdsa - Fatal编程技术网

使用具有Java安全性的openssh公钥(ecdsa-sha2-nistp256)

使用具有Java安全性的openssh公钥(ecdsa-sha2-nistp256),java,openssh,jce,elliptic-curve,ecdsa,Java,Openssh,Jce,Elliptic Curve,Ecdsa,是否有Java库/示例可以将openssh格式的ecdsa公钥读取到Java中的JCEPublicKey?我想用电子商务来解决这个问题 我试图读取的格式是根据授权密钥或Github API(例如):ecdsa-sha2-nistp256 aae2vjzhnhlxnoytibmlzdhanytaaaibmlzdhanytaabbk8hptb72/sfYgNw1WTska2DNOJFx+QhUxuV6OLINSD2ty+6gxcM8yZrvMqWdMePGRb2cGh8L/0bGOk+64IQ/pM

是否有Java库/示例可以将openssh格式的ecdsa公钥读取到Java中的JCE
PublicKey
?我想用电子商务来解决这个问题

我试图读取的格式是根据授权密钥或Github API(例如):
ecdsa-sha2-nistp256 aae2vjzhnhlxnoytibmlzdhanytaaaibmlzdhanytaabbk8hptb72/sfYgNw1WTska2DNOJFx+QhUxuV6OLINSD2ty+6gxcM8yZrvMqWdMePGRb2cGh8L/0bGOk+64IQ/pM=

我找到了这个答案,这对于RSA和DSS来说很好: ,并讨论了ECDSA的openssh格式:

然而,我在尝试将RSS/DSA代码改编为ECDSA时迷失了方向——我不知道如何设置一个新的应用程序。它需要
ECPoint
EllipticCurve
ECParameterSpec
ECField
。openssh格式只包含两个整数,这对于
ECPoint
是有意义的,但我不知道如何设置其余的整数

我在很多图书馆闲逛过,包括《古董》和《古董》。最接近我的是:

com.jcraft.jsch.KeyPair load=com.jcraft.jsch.KeyPair.load(jsch,null,bytes[openSshKey])

它可以很好地加载密钥,但不能让我访问JCE
PublicKey
——只是一个
byte[]getPublicKeyBlob()
方法


我是否遗漏了一些明显的东西?

我已经找到了一种使用Bouncycastle实现这一点的方法(但希望找到一种JCE方法)

修改并引用添加到
decodePublicKey
的以下块中的代码将解析单个BigInt值Q,即“从椭圆曲线点编码的公钥”:

使用Bouncycastle API,我找到了从Q到
ECPublicKey
的解决方案如下(由于提供了起点,请参见):


这将使您从openssh格式的椭圆曲线公钥(
ssh-keygen-t ecdsa-b[256 | 384 | 521]
)转换为JCE
ECPublicKey
,为了完整起见,下面是我使用的代码。它几乎是纯JCE,在助手方法中有少量Bouncycastle(这更新了中的示例代码):


通过使用,我在设置
ECPublicKeySpec
方面取得了一些进展。这提供了一个
ECKey.Curve.P_256.toECParameterSpec()
调用,该调用对大多数神秘参数进行排序。这就剩下了,所以看起来RSA/DSA的例子更有可能被改编。所以,很有趣。我正在修改RSA/DSA示例,得到值“ecdsa-sha2-nistp256”、“nistp256”,然后只得到一个BigInt(而不是两个)。我想知道这是否是“公共部分”,只是因为它是一个公钥?我想是时候阅读了。我发布了一个新问题,关于是否有JCE方法可以做到这一点:我是否可以说服您在github上共享您的项目?我担心我看似相同的问题会被标记为重复你的问题,并且对密码学的理解有限。谢谢——幸好代码在Github上是可见的,至少现在是这样:我会做一个备份以防万一,随时询问它是否消失了。
if (type.startsWith("ecdsa-sha2-") &&
            (type.endsWith("nistp256") || type.endsWith("nistp384") || type.endsWith("nistp521"))) {

        // Based on RFC 5656, section 3.1 (https://tools.ietf.org/html/rfc5656#section-3.1)

        // The string [identifier] is the identifier of the elliptic curve
        // domain parameters.  The format of this string is specified in
        // Section 6.1 (https://tools.ietf.org/html/rfc5656#section-6.1).
        // Information on the REQUIRED and RECOMMENDED sets of
        // elliptic curve domain parameters for use with this algorithm can be
        // found in Section 10 (https://tools.ietf.org/html/rfc5656#section-10).
        String identifier = decodeType();
        if (!type.endsWith(identifier)) {
            throw new IllegalArgumentException("Invalid identifier " + identifier + " for key type " + type + ".");
        }

        // Q is the public key encoded from an elliptic curve point into an
        // octet string as defined in Section 2.3.3 of [SEC1];
        // (https://tools.ietf.org/html/rfc5656#ref-SEC1)
        // point compression MAY be used.
        BigInteger q = decodeBigInt();

        ECPublicKey keyBC = getKeyBC(q, identifier);
        return keyBC;
    }
ECPublicKey getKeyBC(BigInteger q, String identifier) {
    // https://stackoverflow.com/questions/42639620/generate-ecpublickey-from-ecprivatekey
    try {
        // This only works with the Bouncycastle library:
        Security.addProvider(new BouncyCastleProvider());
        // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269#SupportedCurves(ECDSAandECGOST)-NIST(aliasesforSECcurves)
        String name = identifier.replace("nist", "sec") + "r1";
        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
        ECPoint point = ecSpec.getCurve().decodePoint(q.toByteArray());
        ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);
        ECPublicKey publicKey = (ECPublicKey) keyFactory.generatePublic(pubSpec);
        return publicKey;
    } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) {
        throw new RuntimeException(e);
    }
}
...
        } else if (type.startsWith("ecdsa-sha2-") &&
                (type.endsWith("nistp256") || type.endsWith("nistp384") || type.endsWith("nistp521"))) {
            // Based on RFC 5656, section 3.1 (https://tools.ietf.org/html/rfc5656#section-3.1)
            String identifier = decodeType();
            BigInteger q = decodeBigInt();
            ECPoint ecPoint = getECPoint(q, identifier);
            ECParameterSpec ecParameterSpec = getECParameterSpec(identifier);
            ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParameterSpec);
            return KeyFactory.getInstance("EC").generatePublic(spec);
        } ...

/**
 * Provides a means to get from a parsed Q value to the X and Y point values.
 * that can be used to create and ECPoint compatible with ECPublicKeySpec.
 *
 * @param q          According to RFC 5656:
 *                   "Q is the public key encoded from an elliptic curve point into an octet string"
 * @param identifier According to RFC 5656:
 *                   "The string [identifier] is the identifier of the elliptic curve domain parameters."
 * @return An ECPoint suitable for creating a JCE ECPublicKeySpec.
 */
ECPoint getECPoint(BigInteger q, String identifier) {
    String name = identifier.replace("nist", "sec") + "r1";
    ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
    org.bouncycastle.math.ec.ECPoint point = ecSpec.getCurve().decodePoint(q.toByteArray());
    BigInteger x = point.getAffineXCoord().toBigInteger();
    BigInteger y = point.getAffineYCoord().toBigInteger();
    System.out.println("BC x = " + x);
    System.out.println("BC y = " + y);
    return new ECPoint(x, y);
}

/**
 * Gets the curve parameters for the given key type identifier.
 *
 * @param identifier According to RFC 5656:
 *                   "The string [identifier] is the identifier of the elliptic curve domain parameters."
 * @return An ECParameterSpec suitable for creating a JCE ECPublicKeySpec.
 */
ECParameterSpec getECParameterSpec(String identifier) {
    try {
        // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269#SupportedCurves(ECDSAandECGOST)-NIST(aliasesforSECcurves)
        String name = identifier.replace("nist", "sec") + "r1";
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
        parameters.init(new ECGenParameterSpec(name));
        return parameters.getParameterSpec(ECParameterSpec.class);
    } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
        throw new IllegalArgumentException("Unable to get parameter spec for identifier " + identifier, e);
    }
}