给定一个DSAPrivateKey,如何计算相应的DSAPublicKey?

问题描述

在Java中,我有一个DSAPrivateKey,它有一个X参数,还有一个DSAParamsPQ和{{1} }参数。我想计算相应的G。我知道如果知道DSAPublicKeyDSAPublicKeySpecYP,就可以构造Q,然后可以使用G将其变成KeyFactory.generatePublic(KeySpec)的方法。

我不确定的是,在已知DSAPublicKeyYXP的情况下,如何计算Q。我猜答案是:

G

但这会产生异常:

BigInteger y = g.multiply(x).mod(p);

很显然,这种猜测是不正确的。我也尝试过:

Caused by: java.lang.IllegalArgumentException: Y value does not appear to be in correct group
    at org.bouncycastle.crypto.asymmetric.KeyUtils.validated(Unknown Source)
    at org.bouncycastle.crypto.asymmetric.AsymmetricDSAPublicKey.<init>(Unknown Source)
    at org.bouncycastle.jcajce.provider.ProvDSAPublicKey.<init>(Unknown Source)

给出相同的例外。

我使用的是BouncyCastle FIPS版本1.0.2,所以我对使用BouncyCastle类的答案感到满意,但对于不使用BouncyC的类,我也会感到满意

解决方法

您对乘运算正确,以获得值y。我发现了一个非常方便的解决方案,可以与本机Java一起使用。

安全警告:该示例程序没有异常处理,仅用于教育目的。

周末愉快!

这是我的示例程序的(简短)结果:

Derive DSA PublicKey from PrivateKey
publicKey equals publicKeyDerived: true

完整代码:

import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.spec.DSAPublicKeySpec;
import java.util.Arrays;

public class DSA_RetrievePublicKeyFromPrivateKey {
    public static void main(String[] args) throws NoSuchProviderException,NoSuchAlgorithmException {
        System.out.println("Derive DSA PublicKey from PrivateKey");

        KeyPair keyPair = generateDsaKeyPair(2048);
        PublicKey publicKeyOriginal =  keyPair.getPublic(); // original for comparison
        PublicKey publicKeyDerived = deriveDsaPublicKeyFromPrivatekey(keyPair.getPrivate());
        System.out.println("publicKey equals publicKeyDerived: " + Arrays.equals(publicKeyOriginal.getEncoded(),publicKeyDerived.getEncoded()));
    }

    public static KeyPair generateDsaKeyPair(int keylengthInt)
            throws NoSuchAlgorithmException,NoSuchProviderException {
        KeyPairGenerator keypairGenerator = KeyPairGenerator.getInstance("DSA","SUN");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG","SUN");
        keypairGenerator.initialize(keylengthInt,random);
        return keypairGenerator.generateKeyPair();
    }

    public static PublicKey deriveDsaPublicKeyFromPrivatekey (PrivateKey privateKey) throws NoSuchAlgorithmException {
        DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
        DSAParams params = dsaPrivateKey.getParams();
        BigInteger y = params.getG().modPow(dsaPrivateKey.getX(),params.getP());
        DSAPublicKeySpec keySpec = new DSAPublicKeySpec(y,params.getP(),params.getQ(),params.getG());
        PublicKey publicKey;
        KeyFactory keyFactory = KeyFactory.getInstance("DSA");
        try {
            publicKey = keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return publicKey;
    }
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...