Java 给定一个DSAPrivateKey,如何计算相应的DSAPublicKey?
在Java中,我有一个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);
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;
}
}