首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Diffie Hellman密钥交换

Diffie Hellman密钥交换
EN

Stack Overflow用户
提问于 2013-06-22 06:45:35
回答 2查看 7.8K关注 0票数 1

我目前正在尝试使用java密码libray做diffie密钥交换,我已经成功地找到了一个安全的素数和一个生成器。但是,我似乎很难用我找到的值创建DH键。它给了我以下的例外

线程"main“java.security.InvalidAlgorithmParameterException:素数中的异常必须是64的倍数,并且只能在java.security.KeyPairGenerator$Delegate.initialize(Unknown源的java.security.KeyPairGenerator.initialize(Unknown源的DH.createSpecificKey(DH.java:35)和DH.main(DH.java:166)的范围内从512到1024 (包括)。

你们都知道,在密码学中,我们不能让素数变小。如何配合我的安全素数和发生器,以符合卫生署图书馆的标准。

下面是我的源代码

代码语言:javascript
运行
复制
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);


}

希望你们能帮我这个忙。提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2013-07-01 00:47:00

您的目标是使用512位长度:kpg.initialize(512);

您可以生成这样长的p和g:

代码语言:javascript
运行
复制
int bitLength = 1024;
SecureRandom rnd = new SecureRandom();
BigInteger p = BigInteger.probablePrime(bitLength, rnd);
BigInteger g = BigInteger.probablePrime(bitLength, rnd);

probablePrime可能使用Rabin或Strassen测试,它只给出2^-100的机会(几乎没有机会),结果整数不是素数。自2002年a以来,有一种名为AKS ()的多项时间算法来测试素数,以获得100%的确定性(但到目前为止,我还没有见过它的使用,可能2^-100对任何人都有好处)。

票数 2
EN

Stack Overflow用户

发布于 2014-03-11 08:28:23

我想你的问题是,为什么你只能在512位到1024位之间创建素数,而推荐2048位呢?!答案很简单: 2048位与素数无关,而与模数的大小有关,它是两个素数的乘积。两个素数与1024位,每个将给你一个模数2048位。这就是为什么对DH素数使用1024位是安全的。

关于你的例外: Csaba Toth是对的:你的素数太小了,生成它们的方法是次优的。只要使用你的createKey()方法,你就没事了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17248095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档