非对称加密 DH算法

article/2025/10/2 3:38:11

DH算法简介

迪菲-赫尔曼密钥交换(Diffie–Hellman key exchange,缩写为D-H) 是一种安全协议。
它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。
这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。

迪菲-赫尔曼通过公共信道交换一个信息,就可以创建一个可以用于在公共信道上安全通信的对称密钥

交换过程
在这里插入图片描述

原理

最简单,最早提出的个协议使用一个质数p的整数模n乘法群以及其原根g。下面展示这个算法,绿色表示非秘密信息,红色粗体表示秘密信息:
在这里插入图片描述

爱丽丝和鲍伯最终都得到了同样的值,因为在模p下 g^{ab} 和 g^{ba} 相等。 注意a, b 和 g^ab = g^ba mod p 是秘密的。 其他所有的值 p, g, g^a mod p, 以及 g^b mod p 都可以在公共信道上传递。 一旦爱丽丝和鲍伯得出了公共秘密,他们就可以把它用作对称密钥,以进行双方的加密通讯,因为这个密钥只有他们才能得到。

这个问题就是著名的离散对数问题。注意g则不需要很大,并且在一般的实践中通常是2或者5。IETF RFC3526 文档中有几个常用的大质数可供使用。


以下是一个更为一般的描述:

  1. 爱丽丝和鲍伯协商一个有限循环群 G 和它的一个生成元 g。 (这通常在协议开始很久以前就已经规定好; g是公开的,并可以被所有的攻击者看到。)
  2. 爱丽丝选择一个随机自然数 a 并且将 g^a mod p 发送给鲍伯。
  3. 鲍伯选择一个随机自然数 b 并且将 g^b mod p 发送给爱丽丝。
  4. 爱丽丝 计算 g^{ba} mod p
  5. 鲍伯 计算 g^{ab} mod p

java jdk实现

DhUtils.java

package crypto.dh2;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.crypto.*;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;/*** 非对称加密:DH算法 jdk实现* <p>* DH算法的本质就是双方各自生成自己的私钥和公钥,私钥仅对自己可见,然后交换公钥,* 并根据自己的私钥和对方的公钥,生成最终的密钥secretKey,* DH算法通过数学定律保证了双方各自计算出的secretKey是相同的** @link {https://www.cnblogs.com/HKUI/p/DH.html}*/
public class DhUtils {/*** 交换密钥的算法*/private static final String ALGORITHM = "DH";/*** 数据加密的算法*/public static final String DEFAULT_ALGORITHM = "DES";/*** This must be a multiple of 64, ranging from 512 to 1024 (inclusive), or 2048. The default keysize is 1024.*/private static final int DEFAULT_KEY_SIZE = 1024;public static InnerKey generateSenderKey() throws NoSuchAlgorithmException {return generateSenderKey(DEFAULT_KEY_SIZE);}/*** 生成发送者密钥对** @return* @throws Exception*/public static InnerKey generateSenderKey(int keySize)throws NoSuchAlgorithmException {KeyPairGenerator senderGenerator = KeyPairGenerator.getInstance(ALGORITHM);senderGenerator.initialize(keySize);KeyPair senderKeyPair = senderGenerator.generateKeyPair();return InnerKey.builder().publicKey(senderKeyPair.getPublic().getEncoded()).privateKey(senderKeyPair.getPrivate().getEncoded()).build();}/*** 根据发送者公钥;生成接收者密钥对** @param senderPublicKeyBytes 发送者公钥* @return* @throws Exception*/public static InnerKey generateReceiverKey(byte[] senderPublicKeyBytes)throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException {// 根据发送方公钥 初始化接收方密钥KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyBytes);PublicKey senderPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);DHParameterSpec dhParameterSpec = ((DHPublicKey) senderPublicKey).getParams();KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(dhParameterSpec);KeyPair receiverKeyPair = keyPairGenerator.generateKeyPair();return InnerKey.builder().publicKey(receiverKeyPair.getPublic().getEncoded()).privateKey(receiverKeyPair.getPrivate().getEncoded()).build();}/*** 计算密钥** @param publicKeyBytes  公钥* @param privateKeyBytes 私钥* @param algorithm       加密算法* @return* @throws Exception*/public static SecretKey computeSecretKey(byte[] publicKeyBytes, byte[] privateKeyBytes, String algorithm)throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyBytes);PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);KeyAgreement keyAgreement = KeyAgreement.getInstance(keyFactory.getAlgorithm());keyAgreement.init(privateKey);keyAgreement.doPhase(publicKey, true);SecretKey secretKey = keyAgreement.generateSecret(algorithm);return secretKey;}public static byte[] encrypt(byte[] receiverPublicKey, byte[] senderPrivateKey, byte[] data)throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException,BadPaddingException, IllegalBlockSizeException {return encrypt(receiverPublicKey, senderPrivateKey, data, DEFAULT_ALGORITHM);}/*** 发送者加密** @param receiverPublicKey 接收者公钥* @param senderPrivateKey  发送者私钥* @param data              加密数据* @return* @throws Exception*/public static byte[] encrypt(byte[] receiverPublicKey, byte[] senderPrivateKey, byte[] data, String algorithm)throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException,BadPaddingException, IllegalBlockSizeException {SecretKey secretKey = computeSecretKey(receiverPublicKey, senderPrivateKey, algorithm);Cipher cipher = Cipher.getInstance(algorithm);cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(data);return bytes;}public static byte[] decrypt(byte[] senderPublicKey, byte[] receiverPrivateKey, byte[] data)throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException,BadPaddingException, IllegalBlockSizeException {return decrypt(senderPublicKey, receiverPrivateKey, data, DEFAULT_ALGORITHM);}/*** 接收者解密** @param senderPublicKey    发送者公钥* @param receiverPrivateKey 接受者私钥* @param data               解密数据* @return* @throws Exception*/public static byte[] decrypt(byte[] senderPublicKey, byte[] receiverPrivateKey, byte[] data, String algorithm)throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException,BadPaddingException, IllegalBlockSizeException {SecretKey secretKey = computeSecretKey(senderPublicKey, receiverPrivateKey, algorithm);Cipher cipher = Cipher.getInstance(algorithm);cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(data);return bytes;}@Data@NoArgsConstructor@AllArgsConstructor@Builderpublic static class InnerKey {private byte[] publicKey;private byte[] privateKey;}
}

测试代码

package crypto.dh2;import org.apache.commons.codec.binary.Base64;import javax.crypto.SecretKey;
import java.util.Objects;/*** 添加 VM 运行参数: -Djdk.crypto.KeyAgreement.legacyKDF=true*/
public class DhUtilsTest {public static void main(String[] args) throws Exception {String text = "DH算法是一个密钥协商算法,双方最终协商出一个共同的密钥,而这个密钥不会通过网络传输";DhUtils.InnerKey senderKey = DhUtils.generateSenderKey();System.out.println("发送者公钥:" + Base64.encodeBase64String(senderKey.getPublicKey()));System.out.println("发送者私钥:" + Base64.encodeBase64String(senderKey.getPrivateKey()));DhUtils.InnerKey receiverKey = DhUtils.generateReceiverKey(senderKey.getPublicKey());System.out.println("接收者公钥:" + Base64.encodeBase64String(receiverKey.getPublicKey()));System.out.println("接收者私钥:" + Base64.encodeBase64String(receiverKey.getPrivateKey()));String algorithm = "DES";SecretKey senderSecretKey = DhUtils.computeSecretKey(receiverKey.getPublicKey(), senderKey.getPrivateKey(), algorithm);SecretKey receiverSecretKey = DhUtils.computeSecretKey(senderKey.getPublicKey(), receiverKey.getPrivateKey(), algorithm);if (Objects.equals(senderSecretKey, receiverSecretKey)) {System.out.println("密钥生成成功");} else {throw new RuntimeException("密钥生成失败");}// 加密byte[] bytes = DhUtils.encrypt(receiverKey.getPublicKey(), senderKey.getPrivateKey(), text.getBytes(), algorithm);System.out.println("密文:" + Base64.encodeBase64String(bytes));// 解密byte[] result = DhUtils.decrypt(senderKey.getPublicKey(), receiverKey.getPrivateKey(), bytes, algorithm);System.out.println("明文:" + new String(result));}}

code

补充知识

理解 Deffie-Hellman 密钥交换算法 中关于求模公式的说明

假设 q 为素数,对于正整数 a,x,y,有:
(a^x mod p)^y mod p = a^(xy) mod p


http://chatgpt.dhexx.cn/article/ieiKf4vm.shtml

相关文章

DH算法 | Diffie-Hellman 密钥交换

概述&#xff1a; DH 算法又称“Diffie–Hellman 算法”&#xff0c;像往常的算法名字一样&#xff0c;这是用俩个数学牛人的名字来命名的算法&#xff0c;实现安全的密钥交换&#xff0c;通讯双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 优点&am…

DH算法原理

DH算法原理 DH 是 Diffie-Hellman的首字母缩写&#xff0c;是Whitefield与Martin Hellman在1976年提出了一个的密钥交换协议。我个人倾向于称DH算法为 密钥协商协议而RSA算法是密钥交换算法。 本篇分为几个部分&#xff0c;第一个部分介绍一下密钥交换的场景&#xff1b;第二部…

DH、DHE、ECDHE加密算法

DH算法 离散对数 DH 算法是非对称加密算法&#xff0c; 因此它可以用于密钥交换&#xff0c;该算法的核心数学思想是离散对数。 对数运算&#xff1a; i l o g a b i log_{a}b iloga​b 离散对数是在对数运算的基础上加了「模运算」&#xff0c;也就说取余数&#xff0c;…

DH 算法原理

一、DH算法 DH 算法其实也叫作 Diffie - Hellman 密钥交换协议&#xff0c;是一个不安全的秘钥共享网络协议&#xff0c;无法避免中间人攻击。 二、DH算法的原理 假设 Ali 和 Bob 需要互相通信并共享秘钥 Ali 先给 Bob 一个明文共享参数 、 &#xff0c;此信息可以被任何人…

DH算法图解+数学证明

前几天和同事讨论IKE密钥交换流程时&#xff0c;提到了Diffie-Hellman交换。DH算法最主要的作用便是在不安全的网络上成功公共密钥(并未传输真实密钥)。但由于对于DH算法的数学原理则不清楚&#xff0c;因此私下对DH算法进行一个简单学习。 1. DH算法的交互流程&#xff1a; Al…

卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)

本文翻译自 Convolutional Neural Networks(CNNs / ConvNets)&#xff0c;更多内容请访问&#xff1a;http://cs231n.github.io/。 原来译文&#xff1a;https://blog.csdn.net/Consu_Yasin/article/details/78052411 卷积神经网络非常类似于普通的神经网络&#xff1a;它们都…

卷积神经网络CNNs的理解与体会

孔子说过&#xff0c;温故而知新&#xff0c;时隔俩月再重看CNNs&#xff0c;当时不太了解的地方&#xff0c;又有了新的理解与体会&#xff0c;特此记录下来。文章图片及部分素材均来自网络&#xff0c;侵权请告知。 卷积神经网络&#xff08;Convolutinal Neural Networks&a…

Gated-SCNN: Gated Shape CNNs for Semantic Segmentation论文笔记

论文介绍 作者认为之前的semantic segmentation的工作将所有信息都放入到了CNN的网络之中(这其中包含了颜色、边界、纹理等信息)&#xff0c;这不太理想&#xff0c;所以作者在regular stream的基础之上增加了一个shape stream的分支&#xff0c;通过利用门控卷积来控制使得sh…

【t-SNE可视化CNNs特征向量-代码】

t-SNE可视化CNNs特征向量-代码 本博客主要是自己学习记录&#xff0c;参考网络&#xff0c;欢迎指正 整体代码 ModelPath是存放训练好的模型参数的路径 DatasetPath是存放数据集的文件夹的路径&#xff0c;其中不同类别放在不同的子文件夹里也可以参考【t-SNE可视化-代码】 …

CNNs: AlexNet补充

CNNs: AlexNet的补充 导言对AlexNet模型进行调整模型不同层的表征其他探索总结 导言 上上篇和上一篇我们详细地讲述了AlexNet的网络结构和不同超参数对同一数据集的不同实验现象。 本节&#xff0c;我们就AlexNet的一些其他相关问题进行解剖&#xff0c;如修改AlexNet参数量调…

深度学习-浅谈CNNs

偶尔看到了这篇文章&#xff0c;感觉作者写的很容易理解&#xff0c;对于初步认识CNNs有很大的帮助&#xff0c;若想查看原文&#xff0c;请点击此处。 关于神经网络的学习方法&#xff0c;总结起来的要点有以下几点&#xff1a; BP算法 激励函数正则化与交叉验证等其他防止过…

【GSCNN】GSCNN:Gated Shape CNNs for Semantic Segmentation论文记录

目录 简单不看版&#xff1a; 摘要 一、介绍 二、相关工作 三、Gated Shape CNN 代码 四、实验 五&#xff0e;总结 论文&#xff1a;https://arxiv.org/abs/1907.05740 代码&#xff1a;GitHub - nv-tlabs/GSCNN: Gated-Shape CNN for Semantic Segmentation (ICCV 2…

CNNs和视觉Transformer:分析与比较

探索视觉Transformer和卷积神经网络&#xff08;CNNs&#xff09;在图像分类任务中的有效性。 图像分类是计算机视觉中的关键任务&#xff0c;在工业、医学影像和农业等各个领域得到广泛应用。卷积神经网络&#xff08;CNNs&#xff09;是该领域的一项重大突破&#xff0c;被广…

你应该知道的9篇深度学习论文(CNNs 理解)

当时看到英文的博客&#xff0c;本想翻译给感兴趣的同学们看看&#xff0c;没想到已经有人翻译&#xff0c;于是进行了转载&#xff0c;留给自己和更多的人学习&#xff0c;本文仅供参考。 英文博客&#xff1a;https://adeshpande3.github.io/adeshpande3.github.io/The-9-Dee…

【神经网络】CNN

CNN工作原理笔记 卷积神经网络定义卷积运算池化激活函数全连接反向传播算法其他应用延伸知识 首先放个学习视频链接: 大白话讲解卷积神经网络工作原理. 卷积神经网络定义 CNN其实就相当于黑箱&#xff0c;有输入有输出 输入&#xff1a;二维像素阵列 输出&#xff1a;判决结果…

CNN+RNN

CNN,RNN(recurrent, 下同)结合到一起可以建立一个更好的model 1. CRNN&#xff08;先CNN&#xff0c;后RNN&#xff09; References: An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition 一般用于基…

CNNs: ZFNet之CNN的可视化网络介绍

CNNs: ZFNet之CNN的可视化网络介绍 导言Deconvnet1. Unpooling2. ReLU3. Transpose conv AlexNet网络修改AlexNet Deconv网络介绍特征可视化 导言 上一个内容&#xff0c;我们主要学习了AlexNet网络的实现、超参数对网络结果的影响以及网络中涉及到一些其他的知识点&#xff0…

吊炸天的CNNs,这是我见过最详尽的图解!(上)

导读&#xff1a;卷积神经网络&#xff08;CNNs&#xff09;在“自动驾驶”、“人脸识别”、“医疗影像诊断”等领域&#xff0c;都发挥着巨大的作用。这一无比强大的算法&#xff0c;唤起了很多人的好奇心。当阿尔法狗战胜了李世石和柯杰后&#xff0c;人们都在谈论“它”。但…

深度学习—CNN

CNN简介 卷积神经网络 – CNN 最擅长的就是图片的处理。它受到人类视觉神经系统的启发。 CNN 有2大特点&#xff1a; 能够有效的将大数据量的图片降维成小数据量能够有效的保留图片特征&#xff0c;符合图片处理的原则 目前 CNN 已经得到了广泛的应用&#xff0c;比如&…

吊炸天的CNNs,这是我见过最详尽的图解!(下)

【摘要】本文详细介绍了卷积神经网络的运行原理&#xff0c;特别是池化、全连接等过程。为了使大家更快、更轻松的入门&#xff0c;文章没有晦涩难懂的术语和公式&#xff0c;全部采用“图形”的方式来描述。文末的延展阅读部分&#xff0c;更加入了彩色图片卷积原理的手工演算…