给定一个dsaprivatekey,如何计算相应的dsapublickey?

flseospp  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(413)

在 java ,我有一个 DSAPrivateKey ,具有 X 参数,以及 DSAParamsP , Q 以及 G 参数。我想计算相应的 DSAPublicKey . 我知道我可以建造一个 DSAPublicKeySpec 如果我知道 Y , P , Q ,和 G ,然后我就可以使用 KeyFactory.generatePublic(KeySpec) 方法将其转化为 DSAPublicKey .
我不确定的是怎么计算 Y 已知 X , P , 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)

所以很明显这个猜测是不对的。我也试过:

BigInteger y = g.modPow(x, p);

也有同样的例外。
我使用的是bouncycastle fips版本1.0.2,所以我很高兴有一个使用bouncycastle类的答案,但我也很高兴有一个不使用bouncycastle类的答案

lkaoscv7

lkaoscv71#

你用乘法得到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;
    }
}

相关问题