网络安全中的加密、哈希与密钥交换技术
1. TLS 警报消息与超文本传输协议安全
1.1 TLS 警报消息
TLS 警报消息的片段长度设定为 2,携带 2 字节的错误信息。第一个字节表示错误的严重程度(1 为警告,2 为致命),第二个字节通过表 14.2 中的值指示具体错误。当在 TLS 连接上检测到错误时,识别问题的节点会发送警报消息,这可能是对握手过程中消息的响应,也可能是报告连接上数据交换的错误。当发送或接收致命警报消息时,双方会立即关闭连接,且需忘记与该连接相关的所有会话标识符、密钥和机密信息。
| 错误代码 | 严重程度 | 含义 |
|---|---|---|
| 0 | 警告 | close_notify:通知接收方发送方将不再在该连接上发送任何消息(数据或控制)。接收方应回复 close_notify 以终止会话。 |
| 10 | 致命 | unexpected_message:表示协议违规。 |
| 20 | 致命 | bad_record_mac:接收到的记录认证失败。 |
| 21 | 致命 | decryption_failed:由于加密数据的格式问题,解密失败。 |
| 22 | 致命 | record_overflow:接收到的记录长度过大。 |
| 30 | 致命 | decompression_failure:解压缩产生无效记录(例如,解压缩后记录长度过大)。 |
| 40 | 致命 | handshake_failure:在握手过程中无法就可接受的连接参数集达成一致。 |
| 42 | 警告 | bad_certificate:证书已损坏。 |
| 43 | 警告 | unsupported_certificate:使用了不支持的证书类型。 |
| 44 | 警告 | certificate_revoked:证书已被签名者撤销。 |
| 45 | 警告 | certificate_expired:证书已过期。 |
| 46 | 警告 | certificate_unknown:证书因其他原因无法使用。 |
| 47 | 致命 | illegal_parameter:握手过程中交换的某些参数超出范围或未知。 |
| 48 | 致命 | unknown_ca:无法匹配证书颁发机构证书。 |
| 49 | 致命 | access_denied:证书有效,但根据本地策略不允许请求的访问。 |
| 50 | 致命 | decode_error:由于编码错误或参数超出范围,消息无法解码。 |
| 51 | 警告 | decrypt_error:握手加密操作失败,包括无法正确验证签名、解密密钥交换或验证完成消息。 |
| 60 | 致命 | export_restriction:尝试导出密钥失败。 |
| 70 | 致命 | protocol_version:接收到已识别但不支持的协议版本。 |
| 71 | 致命 | insufficient_security:服务器要求的安全性高于客户端提供的安全性时,特定握手失败。 |
| 80 | 致命 | internal_error:发生内部编程错误或资源短缺。 |
| 90 | 警告 | user_canceled:中止当前握手过程。应随后发送 close_notify。 |
| 100 | 警告 | no_renegotiation:拒绝为活动会话进行密码重新协商。 |
1.2 超文本传输协议安全
保障超文本传输协议(HTTP)的安全是互联网安全的重要进展,使得当今许多基于网络的商业活动能够在安全环境中进行。目前有两种策略:
- 安全超文本传输协议(S - HTTP) :是对 HTTP 的一组扩展,在 RFC 2660 中有描述。定义了一个新的 HTTP 方法“Secure”,允许客户端发起加密和密钥信息的交换,以便后续数据消息可以加密或数字签名。RFC 2617 通过为标准 HTTP 方法添加额外字段提供客户端 - 服务器身份验证功能。但 S - HTTP 较少使用,因为它会暴露 HTTP 消息头。
- HTTPS :通过使用安全套接字层(SSL)在 TCP 上运行标准 HTTP 通信。整个 HTTP 通信被封装在 SSL 中并完全加密。对于 HTTPS 操作,URL 以“https://”开头,使用端口号 443 代替标准 HTTP 端口 80。当用户使用 HTTPS 访问安全网站时,通常会看到一个对话框,提示他们接受从 Web 服务器发送的证书。
2. 哈希与加密:算法与密钥
2.1 哈希与加密算法概述
哈希和加密算法用于最基本的身份验证程序和最高级别的数据安全加密。每个算法都将待传输的原始数据和密钥作为输入。密钥是用于锁定和解锁数据的二进制值,长度从 32 位到 256 位或更大。一般来说,对于任何特定算法,密钥越大,破解加密代码就越困难。
身份验证算法使用数据和密钥生成身份验证代码,接收方可以使用相同的密钥对接收的数据运行相同的算法,并将生成的身份验证代码与随数据传输的代码进行比较。加密算法使用密钥将数据转换为一系列看似无意义的字节,接收方必须先解密才能使用这些数据。根据所采用的加密技术,数据可以使用配对算法和与加密时对应的配对密钥进行解密,也可以使用相同的算法和相同的密钥进行解密。
2.2 基本哈希算法 - CRC
最基本的哈希算法是循环冗余校验(CRC),用于 IP 中验证数据是否意外修改,例如在传输过程中因错误导致的修改。它对于检测意外错误非常有价值,但作为身份验证算法毫无用处,因为有已知的方法可以针对数据的任何更改修改 CRC 值。因此,更复杂的哈希算法会结合安全密钥用于身份验证。
2.3 加密算法
加密算法往往更复杂,密钥更长。标准的最小加密算法是数据加密标准(DES),但已经开发出了许多更复杂的方法。
在密码学中使用两种密钥技术:
- 秘密密钥模型 :发送方和接收方都知道并保密密钥,以便成功交换数据。但这种方法需要端点之间进行某种形式的密钥交换,这不仅不安全(因为可能有人拦截密钥交换),而且依赖于发送方和接收方的可信度。例如,一旦接收方知道了发送方的密钥,就可以冒充发送方或拦截其他加密数据。
- 公钥密码学 :使用一个算法但两个密钥,一个用于加密数据,另一个用于解密数据。其中一个密钥公开,另一个保密。例如,希望接收秘密数据的节点会公布要使用的加密密钥,但会保密解密密钥。远程节点使用公布的(公共)加密密钥对数据进行编码,并将其发送给接收方,接收方可以使用秘密密钥进行解码。反之,希望证明其身份的节点会公布公共解密密钥,但保密其加密密钥,这样任何人都可以解码其数字签名,并知道只有拥有秘密加密密钥的所有者才能发送该消息。这种技术可以扩展到消息摘要技术,以提供公钥身份验证。
在实践中,使用两个密钥的算法(双密钥算法)更复杂,操作速度更慢,因为它们需要对每个数据字节进行多次处理,因此不太适合用于批量数据传输。解决方案是使用秘密密钥算法对数据进行编码,然后使用公钥算法对秘密密钥本身进行加密。加密的秘密密钥只需在每次交易中交换一次,就可以用于解码所有数据。
2.4 消息摘要五(MD5)
最常用的简单身份验证哈希算法是消息摘要版本 5(MD5)算法,在 RFC 1321 中有描述,RFC 1828 描述了如何将该算法应用于身份验证。许多协议(如 RSVP)要求支持该算法,并且它是 IPsec 的最低要求。
MD5 可以从任何长度的数据中生成 16 字节的身份验证代码(消息摘要),无论是否使用任何长度的密钥。如果不使用密钥,MD5 可以像 CRC 一样用于检测数据的意外更改,可应用于单个消息、数据结构或整个文件。但由于黑客可以轻松重新计算消息摘要以掩盖对数据的恶意更改,因此会使用密钥(附加或前置到数据),使第三方无法确定修改后数据包的正确 MD5 身份验证代码。
以下是实现 MD5 身份验证算法的示例代码:
/*
Function to perform MD5 digest hashing on a buffer with a key
*/
/*
Returns the message digest in a 16 byte string that is supplied
*/
void MD5(char *input_buffer, char* input_key, char *output_digest)
{
u_int32 digest[4];
u_int32 bit_count[2];
u_char work_buffer[64];
u_char pad_buffer[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
u_char bit_string[8];
u_int32 _buffer_len = strlen(input_buffer);
u_int32 key_len = strlen(input_key);
u_int32 pad_len;
u_int32 ii, jj;
/*
Pre-initialize the digest to well-known values
*/
/*
Placing the low order bytes first, the 16 bytes
*/
/*
should be filled with 0x01 23 45 67 89 ab cd ef
*/
/*
0xfe dc ba 98 76 54 32 10
*/
digest[0] = 0x67452301;
digest[1] = 0xefcdab89;
digest[2] = 0x98badcfe;
digest[3] = 0x10325476;
/* initialize the bit counts
*/
bit_count[0] = 0;
bit_count[1] = 0;
/* Start the digest with the key
*/
if (key_string != NULL) {
_MD5_work(&digest, &bit_count, key_string, key_len, &work_buffer);
/*
Pad to the next 64 byte boundary
*/
pad_len = key_len % 64;
if (pad_len != 0)
_MD5_work(&digest, &bit_count, &pad_buffer, pad_len, &work_buffer);
/* Perform first pass MD5 calculation on the string
*/
_MD5_work(&digest, &bit_count, input_buffer, buffer_len, &work_buffer);
/*
Update the digest with the key (again)
*/
if (key_string != NULL)
_MD5_work(&digest, &bit_count, key_string, key_len, &work_buffer);
/*
Pad the combined string to a length of 56 modulo 64
*/
/*
The value 56 leaves sufficient space for the 8 byte string
*/
/*
representation of the message length
*/
/*
Update the digest with the padding
*/
pad_len = (bit_count[0]/8) % 64;
if (pad_len > 56)
pad_len = pad_len - 56;
else
pad_len = 56 + 64 - pad_len;
if (pad_len != 0)
_MD5_work(&digest, &bit_count, &pad_buffer, pad_len, &work_buffer);
/*
Convert the bit count into a string and add it to the digest
*/
/*
This fits into the last 8 bytes of the work buffer
*/
for (ii = 0; ii < 2; ii ++ )
for (jj = 0; jj < 4; jj ++ )
bit_string[jj + (ii * 4)] = (u_char)((bit_count[ii] >> (jj * 8)) &0xff);
MD5_work(&digest, &bit_count, &bit_string, 8,&work_buffer);
/*
Move digest data into the output string
*/
for (ii = 0; ii < 4; ii ++ )
for (jj = 0; jj < 4; jj ++ )
output_digest[jj + (ii * 4)] = (u_char)((digest[ii] > (jj * 8)) &0xff);
return;
}
}
/*
Function to process a buffer in 64 byte pieces
*/
void _MD5_work (u_int32 *digest, u_int32 *bit_count, u_char *input_buffer,
u_int32 len, u_char *work_buffer)
{
u_int32 bytes_needed;
u_int32 offset = 0;
/* Is the work buffer partially full?
*/
/* If so, how many bytes are needed to fill it up?
*/
bytes_needed = 64 - ((bit_count[0]/8) % 64);
/*
Update count of number of bits added by this string
*/
bit_len = len * 8;
bit_count[0] += bit_len;
if (bit_count[0] < bit_len)
bit_count[1] ++ ;
/* Don’t forget to handle the case where len * 8 overflows
*/
bit_count[1] += ((u_int32)len >> 29);
/* Try to fill up the work buffer and do the hash
*/
while (len > bytes_needed) {
memcpy(work_buffer[64 - bytes_needed], input_buffer[offset], bytes_needed);
_MD5_hash(digest, work_buffer);
len -= bytes_needed;
offset += bytes_needed;
bytes_needed = 64;
}
/*
Copy any spare bytes into the work buffer
*/
if (len > 0) {
assert(len < 64);
memcpy(work_buffer[0], input_buffer[offset], len);
}
return;
}
/*
Function to do the actual MD5 hashing
*/
void _MD5_hash(u_int32 *digest, u_char *work_buffer)
{
u_int32 work_digest[16];
u_int32 ii, jj;
u_int32 a = digest[0], b = digest[1], c = digest[2], d = digest[3];
/*
Convert 64 bytes of buffer into integers
*/
for (ii = 0; ii < 16; ii ++ )
for (jj = 0; jj < 4; jj ++ )
work_digest[ii] += ( (u_int32)(work_buffer[(ii * 4) + jj]) << (jj * 8) );
/*
Now do the ghastly MD5 magic
*/
/*
The following code is taken from RFC1321 and is copyright RSA Data Security,
*/
/*
Inc. to which the following copyright notice applies.
*/
/*
Copyright (C) 1991–2, RSA Data Security, Inc. Created 1991. All rights reserved
*/
/*
License to copy and use this software is granted provided that it is identified
*/
/*
as the “RSA Data Security, Inc. MD5 Message-Digest Algorithm” in all material
*/
/*
mentioning or referencing this software or this function.
*/
/*
License is also granted to make and use derivative works provided that such
*/
/*
works are identified as “derived from the RSA Data Security, Inc. MD5 Message
*/
/*
Digest Algorithm” in all material mentioning or referencing the derived work.
*/
/*
RSA Data Security, Inc. makes no representations concerning either the
*/
/*
merchantability of this software or the suitability of this software for any
*/
/*
particular purpose. It is provided “as is” without express or implied warranty
*/
/*
of any kind.
*/
/*
These notices must be retained in any copies of any part of this documentation
*/
/*
and/or software.
*/
#define F(x, y, z) (((x) &(y)) | ((~x) &(z)))
#define G(x, y, z) (((x) &(z)) | ((y) &(~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define FF(a, b, c, d, x, s, ac)
(a) += F ((b), (c), (d)) + (x) + (u_int32)(ac);
(a) = ROTATE_LEFT ((a), (s));
(a) += (b);
#define GG(a, b, c, d, x, s, ac)
(a) += G ((b), (c), (d)) + (x) + (u_int32)(ac);
(a) = ROTATE_LEFT ((a), (s));
(a) += (b);
#define HH(a, b, c, d, x, s, ac)
(a) += H ((b), (c), (d)) + (x) + (u_int32)(ac);
(a) = ROTATE_LEFT ((a), (s));
(a) += (b);
#define II(a, b, c, d, x, s, ac)
(a) += I ((b), (c), (d)) + (x) + (u_int32)(ac);
(a) = ROTATE_LEFT ((a), (s));
(a) += (b);
/*
Round 1
*/
FF (a, b, c, d, x[ 0], 7, 0xd76aa478);
FF (d, a, b, c, x[ 1], 12, 0xe8c7b756);
FF (c, d, a, b, x[ 2], 17, 0x242070db);
FF (b, c, d, a, x[ 3], 22, 0xc1bdceee);
FF (a, b, c, d, x[ 4], 7, 0xf57c0faf);
FF (d, a, b, c, x[ 5], 12, 0x4787c62a);
FF (c, d, a, b, x[ 6], 17, 0xa8304613);
FF (b, c, d, a, x[ 7], 22, 0xfd469501);
FF (a, b, c, d, x[ 8], 7, 0x698098d8);
FF (d, a, b, c, x[ 9], 12, 0x8b44f7af);
FF (c, d, a, b, x[10], 17, 0xffff5bb1);
FF (b, c, d, a, x[11], 22, 0x895cd7be);
FF (a, b, c, d, x[12], 7, 0x6b901122);
FF (d, a, b, c, x[13], 12, 0xfd987193);
FF (c, d, a, b, x[14], 17, 0xa679438e);
FF (b, c, d, a, x[15], 22, 0x49b40821);
/*
Round 2
*/
GG (a, b, c, d, x[ 1], 5, 0xf61e2562);
GG (d, a, b, c, x[ 6], 9, 0xc040b340);
GG (c, d, a, b, x[11], 14, 0x265e5a51);
GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
GG (a, b, c, d, x[ 5], 5, 0xd62f105d);
GG (d, a, b, c, x[10], 9, 0x2441453);
GG (c, d, a, b, x[15], 14, 0xd8a1e681);
GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
GG (a, b, c, d, x[ 9], 5, 0x21e1cde6);
GG (d, a, b, c, x[14], 9, 0xc33707d6);
GG (c, d, a, b, x[ 3], 14, 0xf4d50d87);
GG (b, c, d, a, x[ 8], 20, 0x455a14ed);
GG (a, b, c, d, x[13], 5, 0xa9e3e905);
GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8);
GG (c, d, a, b, x[ 7], 14, 0x676f02d9);
GG (b, c, d, a, x[12], 20, 0x8d2a4c8a);
/*
Round 3
*/
HH (a, b, c, d, x[ 5], 4, 0xfffa3942);
HH (d, a, b, c, x[ 8], 11, 0x8771f681);
HH (c, d, a, b, x[11], 16, 0x6d9d6122);
HH (b, c, d, a, x[14], 23, 0xfde5380c);
HH (a, b, c, d, x[ 1], 4, 0xa4beea44);
HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9);
HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60);
HH (b, c, d, a, x[10], 23, 0xbebfbc70);
HH (a, b, c, d, x[13], 4, 0x289b7ec6);
HH (d, a, b, c, x[ 0], 11, 0xeaa127fa);
HH (c, d, a, b, x[ 3], 16, 0xd4ef3085);
HH (b, c, d, a, x[ 6], 23, 0x4881d05);
HH (a, b, c, d, x[ 9], 4, 0xd9d4d039);
HH (d, a, b, c, x[12], 11, 0xe6db99e5);
HH (b, c, d, a, x[ 2], 23, 0xc4ac5665);
HH (c, d, a, b, x[15], 16, 0x1fa27cf8);
/*
Round 4
*/
II (a, b, c, d, x[ 0], 6, 0xf4292244);
II (d, a, b, c, x[ 7], 10, 0x432aff97);
II (c, d, a, b, x[14], 15, 0xab9423a7);
II (b, c, d, a, x[ 5], 21, 0xfc93a039);
II (a, b, c, d, x[12], 6, 0x655b59c3);
II (d, a, b, c, x[ 3], 10, 0x8f0ccc92);
II (c, d, a, b, x[10], 15, 0xffeff47d);
II (b, c, d, a, x[ 1], 21, 0x85845dd1);
II (a, b, c, d, x[ 8], 6, 0x6fa87e4f);
II (d, a, b, c, x[15], 10, 0xfe2ce6e0);
II (c, d, a, b, x[ 6], 15, 0xa3014314);
II (b, c, d, a, x[13], 21, 0x4e0811a1);
II (a, b, c, d, x[ 4], 6, 0xf7537e82);
II (d, a, b, c, x[11], 10, 0xbd3af235);
II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
II (b, c, d, a, x[ 9], 21, 0xeb86d391);
/*
Finally update the digest and return
*/
digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
return;
}
MD5 已被发现存在一些安全漏洞,目前正在进行修复工作并设计更安全的替代方案。
2.5 数据加密标准(DES)
数据加密标准(DES)是 IPsec 规定的基本加密算法,由美国国家标准局标准化为联邦信息处理标准出版物 46 - 2(取代 FIPS 46 - 1)。DES 是一种联邦批准的用于加密和解密二进制编码信息的数学算法。
DES 使用最小 64 位的密钥,其中 56 位用于定义密钥本身,8 位(每字节 1 位)用于提供密钥的错误检测。每个字节的第 8 位设置为使字节具有奇偶性,即设置为使字节中设置为 1 的位数为偶数。
定义了四种 DES 操作模式,每种模式都提供了更高的复杂度和更好的安全性:
- 电子密码本(ECB)模式 :直接应用 DES 算法对数据进行加密和解密,其名称来源于过去使用密码本手动编码和解密秘密消息的方式。
- 密码块链接(CBC)模式 :是 ECB 的增强模式,将密文块链接在一起,以增加编码数据的大小和复杂度。
- 密码反馈(CFB)模式 :使用先前生成的密文和要编码的消息作为 DES 算法的输入,有效地将源消息与伪随机字节流链接在一起。
- 输出反馈(OFB)模式 :与 CFB 相同,只是在 OFB 中使用 DES 的先前输出作为输入。
DES 算法非常复杂,这里不详细介绍,如需详细描述,请参考美国国家标准与技术研究院的网页。
3. 密钥交换
3.1 密钥交换的重要性与挑战
密钥的生成和分发是安全系统运行的基础。过去,密钥通常在中央位置“随机”生成,然后使用最可靠的方法分发给加密和解密站点,比如写在纸上手动输入到系统中。
计算机使密钥生成更具随机性,分发也更自由,但问题是密钥传输时不能加密,否则用户无法解读,这使得最敏感的密钥数据容易被拦截。
3.2 双密钥密码学在密钥交换中的应用
如前文所述,双密钥密码学算法允许接收方告知发送方用于编码秘密数据的公共密钥,同时保留单独的秘密密钥用于解码数据。由于公共密钥仅用于加密,其他用户查看也无妨,而用于解密消息的秘密密钥从不暴露。这种方法可用于加密需要在公共网络上交换的其他密钥,避免了对所有消息都应用双密钥加密算法带来的负担。
3.3 因特网密钥交换(IKE)
密钥交换是互联网安全的重要方面,有多个协议涉及此内容,这些协议还用于让加密/解密伙伴协商他们在安全关联(SA)中使用的算法和功能。
因特网密钥交换(IKE)在 RFC 2409 中描述,它是两个先前协议的合并:OAKLEY 密钥交换协议(RFC 2412)和因特网安全关联与密钥管理协议(ISAKMP;RFC 2408)。
3.3.1 ISAKMP 的功能
ISAKMP 提供必要的协商功能,以确定所需的安全级别和使用的算法,还允许端点以最安全的方式交换密钥。同时,该协议包含端点的强身份验证,确保节点确实在与正确的远程节点通信,防止冒名顶替者参与会话并获取可解密的珍贵数据。
ISAKMP 的首要任务是在端点之间建立 SA,这需要通过 TCP 或 UDP 使用端口号 500 进行消息交换,以启动 SA、协商选项、交换公共密钥和身份认证信息。其消息元素与传输层安全握手协议有相似之处,但消息流不同。
3.3.2 ISAKMP 消息格式
每个 ISAKMP 消息以通用消息头开始,用于标识消息和其所属的 SA。消息体由一系列有效负载组成,通用消息头指示第一个有效负载的类型,每个有效负载会告知后续有效负载的类型(如果存在)。有效负载的格式取决于其类型。
| 字段 | 含义 |
|---|---|
| Initiator Cookie | 标识发起方的 SA |
| Responder Cookie | 标识响应方的 SA |
| Major Version | 主版本号 |
| Minor Version | 次版本号 |
| Exchange Type | 指示 ISAKMP 操作模式 |
| E(Encrypted) | 表示有效负载是否加密 |
| C(Commit) | 用于请求在消息内容投入使用前完成完整消息交换 |
| A(Authentication Only) | 表示有效负载应进行身份验证但不加密 |
| Reserved | 保留字段 |
| Message ID | 随机生成的消息 ID,用于关联请求和响应 |
| Message Length | 消息总长度(包括头) |
| First Payload | 第一个有效负载的类型 |
以下是 ISAKMP 消息结构的 mermaid 流程图:
graph LR
A[通用消息头] --> B[有效负载 1]
B --> C{是否有后续有效负载?}
C -- 是 --> D[有效负载 2]
D --> C
C -- 否 --> E[结束]
3.3.3 ISAKMP 交换类型
ISAKMP 有多种交换类型,不同类型决定了端点交换信息的方式和有效负载的组合方式,从而影响信息的保护程度。
| 交换类型 | 含义 |
|---|---|
| 0 | 无 |
| 1 | 基础交换:将密钥交换和身份验证相关信息一起传输,减少往返次数,但不提供身份保护 |
| 2 | 身份保护交换:通过额外的消息交换保护身份交换 |
| 3 | 仅身份验证交换:仅传输身份验证相关信息,不计算密钥 |
| 4 | 激进交换:将安全关联、密钥交换和身份验证有效负载在一个消息中传输,减少消息数量,但不提供身份保护 |
| 5 | 信息交换:用于安全关联管理的单向信息传输 |
3.3.4 不同交换类型的消息流程
- 基础交换 :
- 发起方发送请求,携带安全关联、提案、转换和随机数有效负载,表明要建立 SA 并宣传支持的安全类型和算法。
- 响应方检查随机数,若愿意建立 SA,则回复将应用的安全选项和算法子集。
- 发起方生成密钥并发送身份证明。
- 响应方发送密钥和身份证明,SA 建立完成,开始数据传输。
以下是基础交换的 mermaid 流程图:
graph LR
A[发起方] -->|请求: SA、提案、转换、随机数| B[响应方]
B -->|回复: 安全选项和算法| A
A -->|密钥和身份证明| B
B -->|密钥和身份证明| A
-
身份保护交换 :
- 发起方发送初始请求。
- 响应方回复。
- 引入新的消息交换,交换随机数和密钥。
- 后续身份交换在已建立的密钥保护下进行,并携带哈希有效负载。
-
激进交换 :发起方将安全关联、密钥交换和身份验证有效负载在一个消息中发送,减少消息数量,但身份无法得到有效保护。
综上所述,网络安全中的加密、哈希和密钥交换技术是保障数据安全传输的关键。不同的算法和协议在安全性、性能和应用场景上各有优劣,我们需要根据具体需求选择合适的技术组合,以构建更加安全可靠的网络环境。同时,随着网络攻击手段的不断演变,我们也需要持续关注和研究这些技术的发展,不断提升网络安全防护能力。
超级会员免费看

1170

被折叠的 条评论
为什么被折叠?



