精华内容
下载资源
问答
  • DH 加密算法使用

    万次阅读 2016-08-12 20:56:14
    DH 算法的介绍上面介绍的 DES,3DES,AES 算法都是对称密码算法,所谓对称,在上面也解释了,就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法,属于非对称密码算法,根据对称密码的概念,很容易...

    DH 算法的介绍

    上面介绍的 DES,3DES,AES 算法都是对称密码算法,所谓对称,在上面也解释了,就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法,属于非对称密码算法,根据对称密码的概念,很容易知道,非对称密码算法就是解密和加密过程中使用不同密钥的算法。

    对称密码算法有什么局限呢?由于加密和解密使用相同的数据,所以我们在发送密文的同时,需要将密钥发送给对方,这个时候假如我们的数据和密钥同时被黑客截获了呢?那么我们对数据加密也就失去了意义,唯一保证安全的方法就是,保证密钥不被黑客截取到,怎么才能做到呢?写在纸上亲手交给对方,这样最安全了,但是这往往不可能做到,所以才出现了非对称加密算法。

    DH 算法是怎么加密的呢? 过程比较复杂,首先我们假设发送方是 A,接受方是 B。A 首先生成公钥和密钥,将公钥发送出去,B 接收到 A发送的公钥,然后利用该公钥生成自己的公钥和密钥,再将自己的公钥 发送给 A,这个时候 A 拥有了自己的公钥,密钥和 B 的公钥,B 拥有了自己的公钥密钥和 A 的公钥。

    之后, A 就可以使用 A自己的密钥 + B的公钥 获取到本地的密钥,B也是如此,这个时候 A 和 B 生成的本地密钥其实是相同的,这样的话也就变成了用相同的密钥加密,用相同的密钥解密。而且这样的话,我们数据传递过程中传递的是 A 和 B 的公钥,就算被黑客截取了也无济于事,他们不可能凭借着公钥将数据解密,从而保证了数据的安全性。

    DH 算法的使用

    1 . 首先就是发送方初始化密钥对(公钥 + 密钥)

    public static Map<String,Object> initKey() throws Exception{
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            //初始化密钥对生成器  默认是1024  512-1024 & 64的倍数 
            keyPairGenerator.initialize(1024);
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
    
            DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    
            Map<String,Object> map = new HashMap<>();
            map.put(PUBLIC_KEY, dhPublicKey);
            map.put(PRIVATE_KEY, dhPrivateKey);
    
            return map;
    
        }
    

    2 . 发送方有了自己的公钥和密钥之后,将自己的公钥发送出去,然后接收方根据收到的公钥,提取其中的参数,计算得出自己的公钥和密钥

    public static Map<String,Object> initKey(byte[] key) throws Exception{
            // 将传进来的公钥数组转化为 PublicKey
            X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(key);
    
            // 实例化密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
    
            // 产生公钥
            DHPublicKey dhPublicKey = (DHPublicKey) keyFactory.generatePublic(encodedKeySpec);
    
            // 剖析获取到的公钥,得到其参数
            DHParameterSpec dhParameterSpec = dhPublicKey.getParams();
    
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            keyPairGenerator.initialize(dhParameterSpec);
    
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            DHPublicKey dhPublicKey2 = (DHPublicKey) keyPair.getPublic();
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    
            Map<String,Object> map = new HashMap<>();
            map.put(PUBLIC_KEY, dhPublicKey2);
            map.put(PRIVATE_KEY, dhPrivateKey);
            return map;
        }
    

    3 . 第三步就是根据对方的公钥 + 自己的密钥 计算出本地密钥

    public static byte[] getSecretKey(byte[] publickey,byte[] privateKey) throws Exception{
    
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(publickey);
            DHPublicKey dhPublicKey = (DHPublicKey) keyFactory.generatePublic(encodedKeySpec);
    
            PKCS8EncodedKeySpec encodedKeySpec2 = new PKCS8EncodedKeySpec(privateKey);
            DHPrivateKey dhPrivateKey = (DHPrivateKey) keyFactory.generatePrivate(encodedKeySpec2);
    
            KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
            keyAgreement.init(dhPrivateKey);
            keyAgreement.doPhase(dhPublicKey, true);
    
            SecretKey secretKey = keyAgreement.generateSecret("AES");
            return secretKey.getEncoded();
        }
    

    4 . 测试,根据如上算法,我们看看 发送方计算得出的公钥和密钥以及接收方计算出的公钥和密钥,还有双方的本地密钥

    public static void main(String[] args) throws Exception {
    
            byte[] aPublicKey;
            byte[] aPrivateKey;
            byte[] aSecretKey;
    
            byte[] bPublicKey;
            byte[] bPrivateKey;
            byte[] bSecretKey;
    
            Map<String, Object> aMap = DHUtil.initKey();
            aPublicKey = DHUtil.getPublic(aMap);
            System.out.println("A Public Key : " + Helper.fromByteToHex(aPublicKey));
            aPrivateKey = DHUtil.getPrivate(aMap);
            System.out.println("A Private Key : " + Helper.fromByteToHex(aPrivateKey));
    
            Map<String, Object> bMap = DHUtil.initKey(aPublicKey);
            bPublicKey = DHUtil.getPublic(bMap);
            System.out.println("B Public Key : " + Helper.fromByteToHex(bPublicKey));
            bPrivateKey = DHUtil.getPrivate(bMap);
            System.out.println("B Private Key : " + Helper.fromByteToHex(bPrivateKey));
    
            aSecretKey = DHUtil.getSecretKey(bPublicKey, aPrivateKey);
            System.out.println("A SecretKey : " + Helper.fromByteToHex(aSecretKey));
            bSecretKey = DHUtil.getSecretKey(aPublicKey, bPrivateKey);
            System.out.println("B SecretKey : " + Helper.fromByteToHex(bSecretKey));
    
        }
    

    查看结果如下

    这里写图片描述

    根据生成的本地密钥,发送方和接收方就可以实现数据传输了,和对称密码算法中介绍的 DES,3DES,AES 相同。

    也可以看到,DH 算法中公钥和密钥的长度是非常长的,所以这种方式的加密效率就没有对称算法高,这也是一种牺牲效率去换取安全性的做法。

    展开全文
  • DH算法

    千次阅读 2015-06-05 14:36:01
    1、通信方A和通信方B约定一个初始数g,如g=5,一个质数p,如p=23,g和p是公开的,且1、A生成一个随机数a,a是保密的,如a=63、A计算g^a%p...g^b%p=5^15%23=196、A接收到g^b%p后,再使用保密的a,计算(g^b%p)^a%p=19^6%23

    1、通信方A和通信方B约定一个初始数g,如g=5,一个质数p,如p=23,g和p是公开的,且1< g < p

    2、A生成一个随机数a,a是保密的,如a=6

    3、A计算g^a%p发送给B,g^a%p=5^6%23=8

    4、B生成一个随机数b,b是保密的,如b=15

    5、B计算g^b%p发送给A,g^b%p=5^15%23=19

    6、A接收到g^b%p后,再使用保密的a,计算(g^b%p)^a%p=19^6%23=2

    7、B接收到g^a%p后,再使用保密的b,计算(g^a%p)^b%p=8^15%23=2

    8、这样通信方A和B得到一个相同的密钥:2

    (g^b%p)^a%p=(g^a%p)^b%p的证明:

    如果a=2:

    (g^b%p)^a%p=(g^b%p)^2%p=(g^b-n*p)^2%p=(g^(2*b)-2*g^b*n*p+(n*p)^2)%p=g^(2*b)%p

    可以看出(g^b-n*p)^2展开后除g^(2*b)外,其它都是p的倍数,所以整个算式的结果是g^(2*b)%p

    同理对(g^b-n*p)^a展开后除g^(a*b)外,其它都是p的倍数,所以整个算式的结果是g^(a*b)%p

    同样可以得出(g^a%p)^b%p=g^(a*b)%p

    所以(g^b%p)^a%p=(g^a%p)^b%p

    整个通信过程中g、p、g^a%p、g^b%p是公开的,这时通过g、p、g^a%p得到a比较难,同样通过g、p、g^b%p得到b比较难,所以最终的密钥是比较安全的。

    以g=5、p=23、g^a%p=8计算a为例,a=log(5, (8+23*n)),这个只能将n的可能值逐个带入公式试验才能得到a的值。如果a、p是比较大的数那么计算更加困难。

    如果注意的是,为了防止应用优化算法计算上述问题,质数p不是随便选择的,需要符合一定的条件。随机数a、b的生成算法也必需注意,应使结果尽可能随机,不能出现可预测的规律,否则会使破解变的容易。

    通过上述计算过程也可以看出DH算法不仅可以应用在2方通信的情况,如果多方通信,也可以使用该算法。

    DH密钥交换算法无法验证对方身份,所以DH密钥交换算法不能抵御中间人攻击(MITM,Man-in-the-middle attack)。

    展开全文
  • c语言实现DH算法加密

    2020-01-06 11:38:22
    c语言编写的DH算法,借鉴学习 A系统构建密钥:构建一对公私密钥Private Key1和Public Key1; A系统向B系统公布自己的公钥(Public Key1); B系统使用A公布的公钥(Public Key1)建立一对密钥:Private Key2和...
  • 生成 DH 密钥对 //! \param prime. DH 的 prime. //! \param gen. DH 的 gen. //! \param dh. 返回数据. //! \return. 成功与否. int generate_dh_key(const char *prime, const char *gen, DH *dh) { BIGNUM *p ...
    1. 生成 DH 密钥对
    //! \param prime. DH 的 prime.
    //! \param gen. DH 的 gen.
    //! \param dh. 返回数据.
    //! \return. 成功与否.
    int generate_dh_key(const char *prime, const char *gen, DH *dh) 
    {
    	BIGNUM *p = BN_new();
    	BIGNUM *g = BN_new();
    
    	BN_hex2bn(&p, prime);
    	BN_hex2bn(&g, gen);
    	DH_set0_pqg(dh, p, NULL, g);
    
    	/* generate key */
    	if (1 != DH_generate_key(dh)) {
    		perror("DH_generate_key failed!");
    		return -1;
    	}
    
    	return 0;
    }
    
    
    1. 生成 DH 共享密钥,此处有坑:使用 openssl DH_compute_key() 函数计算 DH 密钥长度不对的问题
    //! \param dh. DH,其中有本端的公钥和私钥.
    //! \param peer_pub_key. 对端 DH 公钥.
    //! \param peer_pub_key_len. 对端 DH 公钥长度.
    //! \param shared_key. 输出 DH 共享密钥.
    //! \return. DH 共享密钥长度.
    int gene_shared_key(DH *dh, uint8_t *peer_pub_key, 
    		uint16_t peer_pub_key_len, unsigned char *shared_key) {
    	BIGNUM *p_pub_key = BN_bin2bn(peer_pub_key, peer_pub_key_len, NULL);
    
    	/* computer shared_dh_secret */
    	int shared_key_len = DH_compute_key_padded(shared_key, p_pub_key, dh);
    	if(-1 == shared_key_len) {
    		perror("DH_compute_key_padded failed!");
    		return -1;
    	}
    
    	return shared_key_len;
    }
    
    1. 中间人攻击
    • 截获双方发送的 DH 公共值
    • 修改为自己的公共值发送给双方
    • 使用两端的公共值同自身的 dh 分别生成中间人到客户端以及中间人到服务器的共享密钥
    • 实现中间人
    展开全文
  • DH算法外传

    千次阅读 2010-11-09 15:30:00
    以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚

    Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。

     

    以下介绍中国馀数定理:

    在中国数学史上,广泛流传着一个“韩信点兵”的故事:
    韩信是汉高祖刘邦手下的大将,他英勇善战,智谋超群,为汉朝的建立了卓绝的功劳。据说韩信的数学水平也非常高超,他在点兵的时候,为了保住军事机密,不让敌人知道自己部队的实力,先令士兵从1至3报数,然后记下最后一个士兵所报之数;再令士兵从1至5报数,也记下最后一个士兵所报之数;最后令士兵从1至7 报数,又记下最后一个士兵所报之数;这样,他很快就算出了自己部队士兵的总人数,而敌人则始终无法弄清他的部队究竟有多少名士兵。
    这个故事中所说的韩信点兵的计算方法,就是现在被称为“中国剩余定理”的一次同余式解法。它是中国古代数学家的一项重大创造,在世界数学史上具有重要的地位。
    最早提出并记叙这个数学问题的,是南北朝时期的数学著作《孙子算经》中的“物不知数”题目。这道“物不知数”的题目是这样的:
    “今有一些物不知其数量。如果三个三个地去数它,则最后还剩二个;如果五个五个地去数它,则最后还剩三个;如果七个七个地去数它,则最后也剩二个。问:这些物一共有多少?”

    下面以现代的语言解说下上面这个式子现在叫做“中国剩余定理”

    用简练的数学语言来表述就是:求这样一个数,使它被3除余2,被5除余3,被7除余2。《孙子算经》给出了这道题目的解法和答案,用算式表示即为:

    70*2 + 21*3 +15*2 - 105*2 =23

    解题步骤

    1.三个质数中两个相乘取得值

    则〔5,7〕=35;〔3,7〕=21;〔3,5〕=15

    以及3个质数的乘积〔3,5,7〕=105

    2.值的倍数除以另外一个数字必须余数为1

    使35被3除余1,用35×2=70   

    使21被5除余1,用21x1=21    //21刚好满足

    使15被7除余1,用15x1=15    //15刚好满足

    3. 与余数相乘之和
    被3除余2,被5除余3,被7除余2

    使35被3除余1,用35×2=70;    70×2   (被3除余) //70=2*5*7=1(mod3)

    使21被5除余1,用21x1=21;    21×3   (被5除余) //21=1*3*7=1(mod5)

    使15被7除余1,用15×1=15;    15×2 (被7除余) //15=1*3*5=1(mod7)

    70×2+21×3+15×2=233

    4. 得出结果

    上一步骤所得结果(233)除以 105 (3×5×7=105) 去余数即使所需答案

    233 / 105 = 2 余数是 23


    70*2 + 21*3 +15*2 - 105*2 =23


    —————————————————————————————————————————————
    用现代的数学术语来说,这幅“开方作法本源图”实际上是一个指数为正整数的二项式定理系数表。稍懂代数的读者都知道:
    N=2(mod3)=3(mode5)=2(mod7)   //式中 = 意思都是恒等,键盘不小的用怎么输入
    《孙子算经》实际上是给出了这类一次同余式组
    N= A(mod3)=B(mod5)=C(mod7)
    一般解:
    N = 70A + 21B + 15C - 105P (p为正整数)

    其中70、21、15和105这四个数是关键,所以后来的数学家把这种解法编成了如下的一首诗歌以便于记诵:

    “三人同行七十(70)稀,
    五树梅花二一(21)枝。
    七子团圆正半月(15),
    除百零五(105)便得知。”



    《孙子算经》的“物不知数”题虽然开创了一次同余式研究的先河,但由于题目比较简单,甚至用试猜的方法也能求得,所以尚没有上升到一套完整的计算程序和理论的高度。真正从完整的计算程序和理论上解决这个问题的,是南宋时期的数学家秦九韶。秦
    九韶在他的《数书九章》(见图1一7一1)中提出了一个数学方法“大衍求一术”,系统地论述了一次同余式组解法的基本原理和一般程序。
    秦九韶为什么要把他的这一套计算程序和基本原理称为“大衍求一术”呢?这是因为其计算程序的核心问题是要“求一”。所谓“求一”,通俗他说,就是求“一个数的多少倍除以另一个数,所得的余数为一”。那么为什么要“求一”呢?我们可以从“物不知数”题的几个关键数字70、21、15中找到如下的规律:

    70=2*5*7=1(mod3)
    21=1*3*7=1(mod5)
    15=1*3*5=1(mod7)

    其中70是5和7的倍数,但被3除余1;21是3和7的倍数,但被5除余1;15是3和5的倍数,但被7除余1,任何一个一次同余式组,只要根据这个规律求出那几个关键数字,那么这个一次同余式组就不难解出了。为此,秦九韶提出了乘率、定数、衍母、衍数等一系列数学概念,并详细叙述了“大衍求一术”的完整过程。(由于解法过于繁细,我们在这里就不展开叙述了,有兴趣的读者可进一步参阅有关书籍。)直到此时,由《孙子算经》“物不知数”题开创的一次同余式问题,才真正得到了一个普遍的解法,才真正上升到了
    “中国剩余定理”的高度。
    从《孙子算经》到秦九韶《数书九章》对一次同余式问题的研究成果,在19世纪中期开始受到西方数学界的重视。1852年,英国传教士伟烈亚力向欧洲介绍了《孙子算经》的“物不知数”题和秦九韶的“大衍求一术”;1876年,德国人马蒂生指出,中国的这一解法与西方19世纪高斯《算术探究》中关于一次同余式组的解法完全一致。从此,中国古代数学的这一创造逐渐受到世界学者的瞩目,并在西方数学史著作中正式被称为“中国剩余定理”。

     

    DH 算法的简要逻辑

    DH 算法的出现就是用来进行密钥传输的。 DH 算法是基于离散对数实现的。用户 A 和 B 如何利用 RSA 算法来传输密钥?

    在通信前, 用户 A 和 B 双方约定 2 个大整数 n 和 g, 其中 1<g<n ,这两个整数可以公开

    1)    A 随机产生一个大整数a ,然后计算Ka =ga mod n 。(a 需要保密)

    2)    B 随机产生一个大整数b ,然后计算Kb =gb mod n 。(b 需要保密)

    3)    A 把Ka 发送给B,B 把Kb 发送给A

    4)    A 计算K=Kb a mod n

    5)    B 计算K=Ka b mod n

    由于Kb a mod n= (gb mod n )a mod n= (ga mod n )b mod n ,因此可以保证双方得到的K 是相同的, K 即是共享的密钥。

     

     

     

    展开全文
  • 加密、认证、DH算法

    2015-05-21 10:42:23
    首先理解加密算法其次理解DH算法最后解析ipsec×××理解加密算法 一个完整的加密方法由很多因素组成,但是最关键的两个因素是加密算法和密钥。加密算法通常是非常复杂的数学公式,这些公式确定如何将明文转化为密文...
  • 初学了一下CryptAPI,主要是需要使用DH算法,经过几天的摸索,把CryptAPI中关于dh算法的东西简单封装了一下,程序主要通过DH算法来获取密钥,然后使用密钥来加密,加密算法可选择des,3des,rc4,加密10M的数据,循环10...
  • 2:DH算法原理: 请求端 与 被请求端 使用同样的密钥生成方法,请求端初始化一对密钥分为公钥和私钥,将公钥作为参数去请求被请求端.被请求端接受请求端的公钥,通过此公钥初始化生成一对密钥.同时将公钥返回给请求端....
  • 今天在使用java实现DH密钥交换算法时,出现了以下错误:出错行在这里:原因分析:由于JDK版本不同,在Java 8 update 161版本以后就会出现此问题,根本原因还是DH密钥长度至少为512位,而AES算法密钥没有这么长,密钥...
  • DH加密算法

    2013-05-11 16:27:36
    DHDiffie-Hellman算法(D-H算法),密钥一致协议。...简单的说就是允许两名用户在公开媒体上交换信息以生成"...以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(Secr...
  • 这个 PD F文件是本人(计算机科学与技术专业)大三下学期的计算机网络课程设计的报告,总共36页。主要内容包括:WireShark使用, Java编程,UDP协议,Diffie-Hellman密钥交换实现,DES加密解密,MD5完整性检测等等。
  • 简单的DH加密算法程序,采用C语言实现,权当学习资料使用; 一共7个函数,加上一个主程序实现; 不用makefile文件编写,直接一个文件编译执行
  • mbedtls系列文章 ...mbedtls | 04 - 对称加密算法的配置与使用(AES算法) mbedtls | 05 - 消息认证码的配置与使用(HMAC算法、GCM算法) mbedtls | 06 - 非对称加密算法的配置与使用(RSA算法) De
  • DH密钥交换算法

    2020-10-14 12:49:20
    简介(百度百科) Whitfield Diffie与Martin Hellman在1976年提出了一个奇妙的密钥交换协议,称为Diffie-Hellman密钥交换协议/算法(Diffie-Hellman Key ...双方确定要用的密钥后,要使用其他对称密钥操作加密算法实...
  • 非对称加密算法之DH算法1. 算法简述2. 模型分析3. 代码实现4. 算法实现分析 1. 算法简述 对称加密算法提高数据安全性,但是带来了密钥管理的复杂性, 如何安全地传递密钥成为棘手问题。密钥交换算法(Diffie-Hellman...
  • 非堆成加密算法DH

    2015-03-26 00:33:12
    DH算法为网络交换数据提供了安全保障。 DH算法,密钥一致协议。 它是这样的,由甲方产出一对密钥(公私钥),乙方按照甲方公钥产生乙方密钥对(公私钥)。 双方使用同一种对车改加密算法构建本地密钥对数据加密。...
  • IPVS调度算法DH

    2019-09-04 20:16:21
    DH(Destination Hashing)调度算法,将报文IP头部的目的地址进行哈希计算,之后根据hash值在由真实服务器组成的buckets数组中查找目标服务器。 调度器注册 DH调度器的定义结构为ip_vs_dh_scheduler,使用函数...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 345
精华内容 138
关键字:

dh算法使用