我目前正在尝试使用java crypto libray来做一个diffie hellman密钥交换,我已经成功地找到了一个安全素数,并且还为它生成了一个生成器。然而,我似乎无法创建一个DH键与我发现的值。这使我有以下异常在线程“主要” java.security.InvalidAlgorithmParameterExceptionDiffie Hellman密钥交换
例外:总理大小必须倍数64,只能从512到1024 com.sun.crypto(含) 。在DH.createSpecificKey处使用java.security.KeyPairGenerator.initialize(未知源) (DH.java :.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120) at java.security.KeyPairGenerator $ Delegate.initialize(Unknown Source) 35) at DH.main(DH.java:166)
大家都知道,在密码学中我们不能让我们的素数很小。我如何满足我的安全素数和发生器以符合DH库的标准。
下面是我的源代码
public static void createKey()throws Exception
{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DiffieHellman");
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman");
DHPublicKeySpec kspec = (DHPublicKeySpec) kfactory.getKeySpec(kp.getPublic(), DHPublicKeySpec.class);
}
public static void createSpecificKey(BigInteger p,BigInteger g)throws Exception
{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DiffieHellman");
DHParameterSpec param = new DHParameterSpec(p,g);
kpg.initialize(param);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman");
DHPublicKeySpec kspec = (DHPublicKeySpec) kfactory.getKeySpec(kp.getPublic(), DHPublicKeySpec.class);
}
static boolean isPrime(long n)
{
if (n%2 == 0)
{
return false;
}
for(int i = 3 ; i*i<=n;i+=2)
{
if(n%i==0)
return false;
}
return true;
}
public static void main(String [] args) throws Exception
{
Random randomGenerator = new Random();
long pValue = randomGenerator.nextInt(1000000);
long gValue = randomGenerator.nextInt(100000);
long correctPValue;
boolean checkPrime = isPrime(pValue);
System.out.println("the number generated is "+pValue);
System.out.println(checkPrime);
while(checkPrime == false)
{
long pValue2 = randomGenerator.nextInt(1000000);
boolean checkPrimeInLoop = isPrime(pValue2);
//System.out.println("value in loop is "+pValue2);
if(checkPrimeInLoop == true)
{
pValue=pValue2;
break;
}
}
long checkSP = (pValue*2)+1;
boolean checkSafePrime = isPrime(checkSP);
//System.out.println(checkSafePrime);
while(checkSafePrime==false)
{
long pValue3=randomGenerator.nextInt(1000000);
boolean checkPrimeInLoop = isPrime(pValue3);
long pValue5=(pValue3*2)+1;
//boolean checkSafePrimeInLoop = isPrime(pValue4);
boolean checkSafePrime2InLoop = isPrime(pValue5);
if(checkSafePrime2InLoop == true && checkPrimeInLoop == true)
{
pValue=pValue3;
break;
}
}
System.out.println("the safe prime is"+pValue);//safe prime
while(gValue>pValue)
{
long gValue2=randomGenerator.nextInt(100000);
if(gValue2<pValue)
{
gValue=gValue2;
break;
}
}
long getDivisor = (pValue-1)/2;
BigInteger bi1,bi2,bi3,bi4;
bi1=BigInteger.valueOf(getDivisor);
bi2 = BigInteger.valueOf(pValue);
bi3 = BigInteger.valueOf(gValue);
bi4= bi3.modPow(bi1,bi2);
long calculatedValue = bi4.longValue();
while(calculatedValue == 1)
{
long gValue3=randomGenerator.nextInt(100000);
long getDivisorInLoop = (pValue-1)/2;
BigInteger bi5,bi6,bi7,bi8;
bi5=BigInteger.valueOf(getDivisorInLoop);
bi6 = BigInteger.valueOf(pValue);
bi7 = BigInteger.valueOf(gValue3);
bi8= bi7.modPow(bi5,bi6);
long calculatedValueInLoop = bi8.longValue();
System.out.println(calculatedValueInLoop);
if(calculatedValueInLoop!=1)
{
gValue=gValue3;
break;
}
}
BigInteger generatorValue,primeValue;
generatorValue = BigInteger.valueOf(gValue);
primeValue = BigInteger.valueOf(pValue);
createKey();
int bitLength=512;
createSpecificKey(generatorValue,primeValue);
}
希望你们能帮助我与此有关。提前致谢!
您是否有理由在较低范围内搜索特定的素数?例外说:“素数大小必须是64的倍数,并且只能在512到1024之间(包含)” –
看起来SSH(等)使用g = 2然后选择一个特殊素数为p使得q mod 12 = 5,然后2q + 1是素数。使用已知算法的某些子组进行高效攻击。 所以这个p和g的选择可能不安全。 – jettero
@jettero我必须阅读这些内容,但是从我的RSA研究中,我认为g = 2是为了加速计算。然而,由于它是如此小的素数,需要非常小心地选择真正的q(和p)以维持该方案的安全性。这是我的两分钱。没有什么比两个长*素数更安全。与g = 2相比,计算将会更长。所以我想说,也许我们应该研究一些常见的实现方式,它们是如何实现的,可能与SSH相似。 –