WebSocket的Sec-WebSocket-Key
是24字节(192位)的Base64编码字符串,解码后为16字节(128位)的原始随机数据;Sec-WebSocket-Accept
是28字节(224位)的Base64编码字符串,解码后为20字节(160位)的SHA-1哈希值。
详细说明:
Sec-WebSocket-Key
- 生成方式:客户端随机生成16字节(128位)的原始数据,经过Base64编码后形成24字节的字符串。
- 示例:
- 原始数据(16字节): dGhlIHNhbXBsZSBub25jZQ==(Base64解码后为 "the sample nonce")
- 编码后(24字节): "dGhlIHNhbXBsZSBub25jZQ=="
Sec-WebSocket-Accept
-
生成步骤 :
- 将客户端的
Sec-WebSocket-Key
与固定字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11
拼接。 - 对拼接后的字符串计算SHA-1哈希(20字节)。
- 将SHA-1哈希进行Base64编码,得到28字节的字符串。
- 示例 :
- 拼接后字符串: "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
SHA-1哈希(20字节): [二进制数据]
Base64编码后(28字节): "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
- 拼接后字符串: "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
代码验证(Java示例):
-
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class WebSocketKeyExample {
public static void main(String[] args) throws NoSuchAlgorithmException {
// 客户端生成的Sec-WebSocket-Key(Base64编码)
String clientKey = "dGhlIHNhbXBsZSBub25jZQ==";
// 1. 解码Base64,验证原始数据长度为16字节
byte[] decodedKey = Base64.getDecoder().decode(clientKey);
System.out.println("Decoded Key Length: " + decodedKey.length + " bytes"); // 输出16
// 2. 拼接固定字符串并计算SHA-1
String magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
String concatenated = clientKey + magicString;
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
byte[] hash = sha1.digest(concatenated.getBytes());
// 3. Base64编码SHA-1哈希,验证输出长度为28字节
String acceptKey = Base64.getEncoder().encodeToString(hash);
System.out.println("Sec-WebSocket-Accept Length: " + acceptKey.length() + " bytes"); // 输出28
}
}
-
输出结果:
Decoded Key Length: 16 bytes Sec-WebSocket-Accept Length: 28 bytes
关键点总结:
-
Sec-WebSocket-Key
:客户端发送的Base64字符串,解码后固定为16字节。 -
Sec-WebSocket-Accept
:服务器计算的Base64字符串,编码后固定为28字节。 -
协议依据:RFC 6455(WebSocket协议标准)
- 将客户端的
-