阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

密钥交换算法

28次阅读
没有评论

共计 2788 个字符,预计需要花费 7 分钟才能阅读完成。

对称加密算法解决了数据加密的问题。我们以 AES 加密为例,在现实世界中,小明要向路人甲发送一个加密文件,他可以先生成一个 AES 密钥,对文件进行加密,然后把加密文件发送给对方。因为对方要解密,就必须需要小明生成的密钥。

现在问题来了:如何传递密钥?

在不安全的信道上传递加密文件是没有问题的,因为黑客拿到加密文件没有用。但是,如何如何在不安全的信道上安全地传输密钥?

要解决这个问题,密钥交换算法即 DH 算法:Diffie-Hellman 算法应运而生。

DH 算法解决了密钥在双方不直接传递密钥的情况下完成密钥交换,这个神奇的交换原理完全由数学理论支持。

我们来看 DH 算法交换密钥的步骤。假设甲乙双方需要传递密钥,他们之间可以这么做:

  1. 甲首先选择一个素数 p,例如 97,底数gp的一个原根,例如 5,随机数 a,例如 123,然后计算A=g^a mod p,结果是 34,然后,甲发送p=97g=5A=34 给乙;
  2. 乙方收到后,也选择一个随机数b,例如,456,然后计算B = g^b mod p,结果是 75,乙再同时计算s = A^b mod p,结果是 22;
  3. 乙把计算的 B=75 发给甲,甲计算s = B^a mod p,计算结果与乙算出的结果一样,都是 22。

所以最终双方协商出的密钥 s 是 22。注意到这个密钥 s 并没有在网络上传输。而通过网络传输的 pgAB是无法推算出 s 的,因为实际算法选择的素数是非常大的。

所以,更确切地说,DH 算法是一个密钥协商算法,双方最终协商出一个共同的密钥,而这个密钥不会通过网络传输。

如果我们把 a 看成甲的私钥,A看成甲的公钥,b看成乙的私钥,B看成乙的公钥,DH 算法的本质就是双方各自生成自己的私钥和公钥,私钥仅对自己可见,然后交换公钥,并根据自己的私钥和对方的公钥,生成最终的密钥 secretKey,DH 算法通过数学定律保证了双方各自计算出的secretKey 是相同的。

使用 Java 实现 DH 算法的代码如下:

import java.security.*;
import java.security.spec.*;
import javax.crypto.KeyAgreement;
import java.util.HexFormat;

public class Main {public static void main(String[] args) {// Bob 和 Alice:
        Person bob = new Person("Bob");
        Person alice = new Person("Alice");

        // 各自生成 KeyPair:
        bob.generateKeyPair();
        alice.generateKeyPair();

        // 双方交换各自的 PublicKey:
        // Bob 根据 Alice 的 PublicKey 生成自己的本地密钥:
        bob.generateSecretKey(alice.publicKey.getEncoded());
        // Alice 根据 Bob 的 PublicKey 生成自己的本地密钥:
        alice.generateSecretKey(bob.publicKey.getEncoded());

        // 检查双方的本地密钥是否相同:
        bob.printKeys();
        alice.printKeys();
        // 双方的 SecretKey 相同,后续通信将使用 SecretKey 作为密钥进行 AES 加解密...
    }
}

class Person {public final String name;

    public PublicKey publicKey;
    private PrivateKey privateKey;
    private byte[] secretKey;

    public Person(String name) {this.name = name;
    }

    // 生成本地 KeyPair:
    public void generateKeyPair() {try {KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");
            kpGen.initialize(512);
            KeyPair kp = kpGen.generateKeyPair();
            this.privateKey = kp.getPrivate();
            this.publicKey = kp.getPublic();} catch (GeneralSecurityException e) {throw new RuntimeException(e);
        }
    }

    public void generateSecretKey(byte[] receivedPubKeyBytes) {try {// 从 byte[]恢复 PublicKey:
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(receivedPubKeyBytes);
            KeyFactory kf = KeyFactory.getInstance("DH");
            PublicKey receivedPublicKey = kf.generatePublic(keySpec);
            // 生成本地密钥:
            KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
            keyAgreement.init(this.privateKey); // 自己的 PrivateKey
            keyAgreement.doPhase(receivedPublicKey, true); // 对方的 PublicKey
            // 生成 SecretKey 密钥:
            this.secretKey = keyAgreement.generateSecret();} catch (GeneralSecurityException e) {throw new RuntimeException(e);
        }
    }

    public void printKeys() {System.out.println("Name:" + this.name);
        System.out.println("Private key:" + HexFormat.of().formatHex(this.privateKey.getEncoded()));
        System.out.println("Public key:" + HexFormat.of().formatHex(this.publicKey.getEncoded()));
        System.out.println("Secret key:" + HexFormat.of().formatHex(this.secretKey));
    }
}

但是 DH 算法并未解决中间人攻击,即甲乙双方并不能确保与自己通信的是否真的是对方。消除中间人攻击需要其他方法。

练习

使用 DH 算法生成密钥。

下载练习

小结

DH 算法是一种密钥交换协议,通信双方通过不安全的信道协商密钥,然后进行对称加密传输。

DH 算法没有解决中间人攻击。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2788字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中