Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.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 给定一个DSAPrivateKey,如何计算相应的DSAPublicKey?_Java_Cryptography_Bouncycastle_Public Key Encryption_Dsa - Fatal编程技术网

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

Java 给定一个DSAPrivateKey,如何计算相应的DSAPublicKey?,java,cryptography,bouncycastle,public-key-encryption,dsa,Java,Cryptography,Bouncycastle,Public Key Encryption,Dsa,在Java中,我有一个DSAPrivateKey,它有一个X参数,还有一个DSAParams,带有p、Q和G参数。我想计算相应的DSAPublicKey。我知道如果我知道Y、P、Q和G,我可以构造一个DSAPublicKeySpec,然后我可以使用KeyFactory.generatePublic(KeySpec)方法将其转换为DSAPublicKey 我不确定的是,在已知X、p、Q和G的情况下,如何计算Y。我猜答案是: BigInteger y = g.multiply(x).mod(p);

在Java中,我有一个
DSAPrivateKey
,它有一个
X
参数,还有一个
DSAParams
,带有
p
Q
G
参数。我想计算相应的
DSAPublicKey
。我知道如果我知道
Y
P
Q
G
,我可以构造一个
DSAPublicKeySpec
,然后我可以使用
KeyFactory.generatePublic(KeySpec)
方法将其转换为
DSAPublicKey

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

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;
    }
}

谢谢,成功了。原来我的代码几乎和你的代码一样,我的实际问题是我在新的DSAPublicKeySpec(y,params.getP(),params.getQ(),params.getG())行中意外地交换了Q和G。我想这表明我应该分享我的全部代码。(另外,我可以确认本机Java和BouncyCastle FIPS不是问题,两种情况下都可以使用相同的代码。)
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;
    }
}