加密与安全部分 实验及知识点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加密与安全部分 实验及知识点相关的知识,希望对你有一定的参考价值。
1、实验:A,B,C三台主机,A通过B连接通C
A:centos7(192。168.93.254)B:centos6(192.168.93.253)C:R1(192.168.93.200)
首先假设 C主机做过防火墙策略,禁止被A直接连接通
Iptables -A INPUT -s (A的IP) -j REJECT
[[email protected] ~]# iptables -A INPUT -s 192.168.93.254 -j REJECT
因为A和C连接,B为跳板,无需拒绝B
此时A连接C不通,而A可以连接上B,再连接C,此过程较繁琐
我们可以ssh -t (B的IP) ssh (C的IP)
[[email protected] .ssh]# ssh -t 192.168.93.253 ssh 192.168.93.200
[[email protected] ~]# ip a
输入密码即可登录C主机成功
然而此时C觉得是B在连接,而非A在连接
[[email protected] ~]# ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.93.200:22 192.168.93.253:52586
我们也可以一次性输入一条命令执行完就退出,如下:
[[email protected] .ssh]# ssh -t 192.168.93.253 ssh 192.168.93.200 ‘ip a‘
[email protected]‘s password:
[email protected]‘s password:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:33:b4:1a brd ff:ff:ff:ff:ff:ff
inet 192.168.93.200/24 brd 192.168.93.255 scope global noprefixroute ens33
3、在centos7 上登录centos6 不用输入用户名密码,而是基于key验证
步骤:1、先生成公私秘钥对儿
A、[[email protected] ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again: (此处三项默认回车即可)
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:OKPv+40SVvZ+6EcyyrMbKV1fQkfca03waBBl3+a816I [email protected]
The key‘s randomart image is:
+---[RSA 2048]----+
| o+=o |
| +.++|
| . +.B|
| .o . o *.|
| +oS.. . o o|
| .o+ o+..o o|
| ...o+o =. ..o|
| ...++o o. ..|
| .++==ooE |
+----[SHA256]-----+
B、[[email protected] ~]# cd .ssh
[[email protected] .ssh]# ll
total 12
-rw------- 1 root root 1679 Jan 24 21:01 id_rsa
-rw-r--r-- 1 root root 406 Jan 24 21:01 id_rsa.pub
-rw-r--r-- 1 root root 396 Jan 24 15:07 known_hosts
此处生成的id_rsa 与 id_rsa.pub 为公私钥文件
C、(把公钥文件传输至远程服务器对应用户的家目录)
[[email protected] ~]# ssh-copy-id -i /root/.ssh/id_rsa 192.168.93.253
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]‘s password:
此操作是将私钥文件传给远程主机,然而本应该传送的是公钥文件,上方的需正常输入密码
D、[[email protected] .ssh]# ll
total 8
-rw------- 1 root root 406 Jan 24 20:11 authorized_keys
-rw-r--r-- 1 root root 1188 Jan 24 16:35 known_hosts
[[email protected] .ssh]# cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEMjCxmlo89MO7Vr+KcwqL//WXJV0nJ/o8AQYAIBv1E9b31e1QZUKNRCcmz+y8a6z5qN0uQM5PmdrNTtrL1/vE68Z4pcr6KzwaiD1xloaB0tIliO+gzgjOfe3jrikdzSWuV+QyYQQArYHLNPKWMbJ6PHNJCfbd/mErdUh5lxblwU62Z8GkD382tt8BdfouSjTLuYPCR0AR6NmRUPBfDF5VmvL9YUEhFUYYxflYfxHwqGN/sfLaYLfbPXowhZx65W8KldNOva5xy8RrWq2f2bSb2cQEd2/zkYlTPkF6xzsNraOEY6SfpLesZH7IQ5hqHkmhoEkAl/GkdGod+b0m16XF [email protected]
然而,我们在centos6上面_查看 cat authorizedkeys 文件,它是公钥,而非私钥与centos7的显示一模一样 如下:
[[email protected] ~]# cat .ssh/id_rsa.pub
ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQDEMjCxmlo89MO7Vr+KcwqL//WXJV0nJ/o8AQYAIBv1E9b31e1QZUKNRCcmz+y8a6z5qN0uQM5PmdrNTtrL1/vE68Z4pcr6KzwaiD1xloaB0tIliO+gzgjOfe3jrikdzSWuV+QyYQQArYHLNPKWMbJ6PHNJCfbd/mErdUh5lxblwU62Z8GkD382tt8BdfouSjTLuYPCR0AR6NmRUPBfDF5VmvL9YUEhFUYYxflYfxHwqGN/sfLaYLfbPXowhZx65W8KldNOva5xy8RrWq2f2bSb2cQEd2/zkYlTPkF6xzsNraOEY6SfpLesZH7IQ5hqHkmhoEkAl/GkdGod+b0m16XF [email protected]
E、[[email protected] ~]# ssh 192.168.93.253
Last login: Thu Jan 24 19:04:01 2019 from 192.168.93.1
此时,我们远程连接主机,实现成功登陆,我们就可以远程操作主机,例如:[[email protected] ~]# ssh 192.168.93.253 hostname
centos6.localdomain
4、使用export将100台主机批量实现key验证
实验目标:创建一个脚本,将生成的公钥传送到所有管理的主机上
准备:A、假设所有主机密码一样,把所有的口令都设为同一个,eg:echo magedu |passwd --stdin root
B、创建一个hosts.txt文件,将所管控的主机IP地址列在其中,
C、[[email protected] ~]# cat ssh_key_push.sh
#!/bin/bash
ssh-keygen -P "" -f /root/.ssh/id_rsa (“”:设置的空口令) (此命令可一次性生成公私钥对儿)
pass=magedu
rpm -q expect &> /dev/null || yum install expect -y -q (静默安装expect)
while read ip ;do
expect <<EOF
set timeout 20
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $ip
expect {
"yes/no" { send "yes
";exp_continue }
"password" { send "$pass
" }
}
expect eof
EOF
done < host.txt
D、脚本一竣工,我们将其加权限:chmod +x ssh_key_push.sh
E、./ssh_key_push.sh 运行完毕,即可连接远程主机
F、[[email protected] ~]# ssh 192.168.93.253
Last login: Thu Jan 24 21:40:10 2019 from 192.168.93.1
[[email protected] ~]# exit
logout
Connection to 192.168.93.253 closed.
[[email protected] ~]# ssh 192.168.93.200
Last login: Thu Jan 24 22:41:15 2019 from 192.168.93.1
[[email protected] ~]# exit
logout
对称加密算法
对称加密:加密和解密使用同一个密钥
DES:Data Encryption Standard,56bits
3DES:
AES:Advanced (128, 192, 256bits)
Blowfish,Twofish
IDEA,RC6,CAST5
?特性:
1、加密、解密使用同一个密钥,效率高
2、将原始数据分割成固定大小的块,逐个进行加密
?缺陷:
1、密钥过多
2、密钥分发
3、数据来源无法确认
非对称加密算法
公钥加密:密钥是成对出现
公钥:公开给所有人;public key
私钥:自己留存,必须保证其私密性;secret key
特点:用公钥加密数据,只能使用与之配对的私钥解密;反之亦然
功能:
数字签名:主要在于让接收方确认发送方身份
对称密钥交换:发送方用对方的公钥加密一个对称密钥后发送给对方
数据加密:适合加密较小数据
缺点:密钥长,加密解密效率低下
算法:
RSA(加密,数字签名)
DSA(数字签名)
ELGamal
非对称加密
?基于一对公钥/密钥对
? 用密钥对中的一个加密,另一个解密
?实现加密:
? 接收者
生成公钥/密钥对:P和S
公开公钥P,保密密钥S
? 发送者
使用接收者的公钥来加密消息M
将P(M)发送给接收者
? 接收者
使用密钥S来解密:M=S(P(M))
非对称加密
实现数字签名:
? 发送者
生成公钥/密钥对:P和S
公开公钥P,保密密钥S
使用密钥S来加密消息M
发送给接收者S(M)
? 接收者
使用发送者的公钥来解密M=P(S(M))
结合签名和加密
分离签名
实验:用对称、非对称、哈希算法
A----->B A 发的数据只有B能解,B也知道只能是A发的
Key { data+Sa [ hash ( data ) ] } + Pb (key)
解析:
A向B发数据时,在原始数据data后加A的私钥签名,[hash(data)]为哈希算法对数据做的摘要,此串数据 data+Sa [ hash ( data ) ]用对称秘钥key加密,拿对方B的公钥把对称秘钥key加密,
B接收A的数据时,因为只有B可解,B的私钥解开对称秘钥key可得到data数据,但是数据来源不确定,就用A的公钥解开,得到的数据是一串,把前面第一个data数据用哈希算法得出结果,与后面的第二个data作比较,若结果一样,说明数据来源是A.
单向散列
?将任意数据缩小成固定大小的“指纹”
? 任意长度输入
? 固定长度输出
? 若修改数据,指纹也会改变(“不会产生冲突”)
? 无法从指纹中重新生成数据(“单向”)
?功能:数据完整性
?常见算法
md5: 128bits、sha1: 160bits、sha224、sha256、sha384、sha512
?常用工具
? md5sum | sha1sum [ --check ] file
? openssl、gpg
? rpm -V
使用gpg实现对称加密
?对称加密file文件
gpg -c file
ls file.gpg
在另一台主机上解密file
gpg -o file -d file.gpg
使用gpg工具实现公钥加密
在hostB主机上用公钥加密,在hostA主机上解密
在hostA主机上生成公钥/私钥对
gpg --gen-key
?在hostA主机上查看公钥
gpg --list-keys
?在hostA主机上导出公钥到wang.pubkey
gpg -a --export -o wang.pubkey
?从hostA主机上复制公钥文件到需加密的B主机上
scp wang.pubkey hostB:
在需加密数据的hostB主机上生成公钥/私钥对
gpg --list-keys
gpg --gen-key
在hostB主机上导入公钥
gpg --import wang.pubkey
gpg --list-keys
用从hostA主机导入的公钥,加密hostB主机的文件file,生成file.gpg
gpg -e -r wangxiaochun file
file file.gpg
复制加密文件到hostA主机
scp fstab.gpg hostA:
在hostA主机解密文件
gpg -d file.gpg
gpg -o file -d file.gpg
删除公钥和私钥
gpg --delete-keys wangxiaochun
gpg --delete-secret-keys wangxiaochun
openssl命令
生成密钥对儿:man genrsa
生成私钥
openssl genrsa -out /PATH/TO/PRIVATEKEY.FILE NUM_BITS
(umask 077; openssl genrsa –out test.key –des 2048)
openssl rsa -in test.key –out test2.key 将加密key解密
?从私钥中提取出公钥
openssl rsa -in PRIVATEKEYFILE –pubout –out PUBLICKEYFILE
openssl rsa –in test.key –pubout –out test.key.pub
?随机数生成器:伪随机数字
键盘和鼠标,块设备中断
/dev/random:仅从熵池返回随机数;随机数用尽,阻塞
/dev/urandom:从熵池返回随机数;随机数用尽,会利用软件生成伪随机数,非阻塞
ssh客户端
?客户端组件:
?ssh, 配置文件:/etc/ssh/ssh_config
Host PATTERN
StrictHostKeyChecking no 首次登录不显示检查提示
? 格式:ssh [[email protected]]host [COMMAND]
ssh [-l user] host [COMMAND]
? 常见选项
-p port:远程服务器监听的端口
-b:指定连接的源IP
-v:调试模式
-C:压缩方式
-X:支持x11转发
-t:强制伪tty分配
ssh -t remoteserver1 ssh -t remoteserver2 ssh remoteserver3
ssh服务基于密钥登录验证
?基于密钥的登录方式
1 首先在客户端生成一对密钥(ssh-keygen)
2 并将客户端的公钥ssh-copy-id 拷贝到服务端
3 当客户端再次发送一个连接请求,包括ip、用户名
4 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:magedu
5 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端
6 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
7服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录
基于key认证实现
?基于密钥的认证:
?(1) 在客户端生成密钥对
ssh-keygen -t rsa [-P ‘‘] [-f “~/.ssh/id_rsa"]
?(2) 把公钥文件传输至远程服务器对应用户的家目录
ssh-copy-id [-i [identity_file]] [[email protected]]host
?(3) 测试
?(4) 在SecureCRT或Xshell实现基于key验证
在SecureCRT工具—>创建公钥—>生成Identity.pub文件
转化为openssh兼容格式(适合SecureCRT,Xshell不需要转化格式),并复制到需登录主机上相应文件authorized_keys中,注意权限必须为600,在需登录的ssh主机上执行:ssh-keygen -i -f Identity.pub >> .ssh/authorized_keys
基于key认证
?(5)重设私钥口令:
ssh-keygen –p
?(6)验证代理(authentication agent)保密解密后的密钥
? 这样口令就只需要输入一次
? 在GNOME中,代理被自动提供给root用户
? 否则运行ssh-agent bash
?(7)钥匙通过命令添加给代理
ssh-add
rsync命令
? 基于ssh和rsh服务实现高效率的远程系统之间复制文件
? 使用安全的shell连接做为传输方式
? rsync -av /etc server1:/tmp 复制目录和目录下文件
? rsync -av /etc/ server1:/tmp 只复制目录下文件
? 比scp更快,只复制不同的文件
? 常用选项:
-n 模拟复制过程
-v 显示详细过程
-r 递归复制目录树
-p 保留权限
-t 保留时间戳
-g 保留组信息
-o 保留所有者信息
-l 将软链接文件本身进行复制(默认)
-L 将软链接文件指向的文件复制
-a 存档,相当于–rlptgoD,但不保留ACL(-A)和SELinux属性(-X)
pssh示例
?通过pssh批量关闭seLinux
pssh -H [email protected] -i ‘sed -i
"s/^SELINUX=.*/SELINUX=disabled/" /etc/selinux/config’
?批量发送指令
pssh -H [email protected] -i setenforce 0
pssh -H [email protected] -i hostname
?当不支持ssh的key认证时,通过 -A选项,使用密码认证批量执行指令
pssh -H [email protected] -A -i hostname
?将标准错误和标准正确重定向都保存至/app目录下
pssh -H 192.168.1.10 -o /app -e /app -i “hostname”
pscp.pssh命令
?pscp.pssh功能是将本地文件批量复制到远程主机
?pscp [-vAr] [-h hosts_file] [-H [[email protected]]host[:port]] [-l user] [-p par] [-o
outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] local remote
?pscp-pssh选项
-v 显示复制过程
-r 递归复制目录
?将本地curl.sh 复制到/app/目录
pscp.pssh -H 192.168.1.10 /root/test/curl.sh /app/
pscp.pssh -h host.txt /root/test/curl.sh /app/
?将本地多个文件批量复制到/app/目录
pscp.pssh -H 192.168.1.10 /root/f1.sh /root/f2.sh /app/
?将本地目录批量复制到/app/目录
pscp.pssh -H 192.168.1.10 -r /root/test/ /app/
pslurp命令
?pslurp功能是将远程主机的文件批量复制到本地
?pslurp [-vAr] [-h hosts_file] [-H [[email protected]]host[:port]] [-l user] [-p par][-o
outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] [-L localdir]
remote local(本地名)
?pslurp选项
-L 指定从远程主机下载到本机的存储的目录,local是下载到本地后的名称 -r 递归复制目录
批量下载目标服务器的passwd文件至/app下,并更名为user
pslurp -H 192.168.1.10 -L /app /etc/passwd user
?SSH 端口转发能够提供两大功能:
?加密 SSH Client 端至 SSH Server 端之间的通讯数据
?突破防火墙的限制完成一些之前无法建立的 TCP 连接
SSH端口转发
?本地转发:
-L localport:remotehost:remotehostport sshserver
?选项:
-f 后台启用
-N 不打开远程shell,处于等待状态
-g 启用网关功能
?示例
ssh –L 9527:telnetsrv:23 -Nfg sshsrv
telnet 127.0.0.1 9527
当访问本机的9527的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发到telnetsrv:23data ? ? localhost:9527 ? ? localhost:XXXXX ? ? sshsrv:22 sshsrv:YYYYY ? ? telnetsrv:23
SSH端口转发
?远程转发:
-R sshserverport:remotehost:remotehostport sshserver
?示例:
ssh –R 9527:telnetsrv:23 –Nf sshsrv
让sshsrv侦听9527端口的访问,如有访问,就加密后通过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv:23
Data ? ? sshsrv:9527 ? ? sshsrv:22 ? ? localhost:XXXXX ? ?
localhost:YYYYY ? ? telnetsrv:23
SSH端口转发
?动态端口转发:
?当用firefox访问internet时,本机的1080端口做为代理服务器,firefox的访问请求被转发到sshserver上,由sshserver替之访问internet
ssh -D 1080 [email protected] -fNg
在本机firefox设置代理socket proxy:127.0.0.1:1080
curl --socks5 127.0.0.1:1080 http://www.google.com
sudo
?配置文件:/etc/sudoers, /etc/sudoers.d/
?时间戳文件:/var/db/sudo
?日志文件:/var/log/secure
?配置文件支持使用通配符glob
? 任意单一字符
- 匹配任意长度字符
[wxc] 匹配其中一个字符
[!wxc] 除了这三个字符的其它字符
x 转义
[[alpha]] 字母 示例: /bin/ls [[alpha]]*
?配置文件规则有两类
1、别名定义:不是必须的
2、授权规则:必须的
sudoers
?授权规则格式:
用户 登入主机=(代表用户) 命令
?示例:
root ALL=(ALL) ALL
?格式说明:
user: 运行命令者的身份
host: 通过哪些主机
(runas):以哪个用户的身份
command: 运行哪些命令
sudo别名和示例
?别名有四种类型:User_Alias, Runas_Alias, Host_Alias ,CmndAlias
?别名格式:[A-Z]([A-Z][0-9])
?别名定义:
Alias_Type NAME1 = item1, item2, item3 : NAME2 = item4, item5
?示例1:
Student ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
?示例2:
student ALL=(root) /sbin/pidof,/sbin/ifconfig
%wheel ALL=(ALL) NOPASSWD: ALL
sudo示例
?示例3
User_Alias NETADMIN= netuser1,netuser2
Cmnd_Alias NETCMD = /usr/sbin/ip
NETADMIN ALL=(root) NETCMD
?示例4
User_Alias SYSADER=wang,mage,%admins
User_Alias DISKADER=tom
Host_Alias SERS=www.magedu.com,172.16.0.0/24
Runas_Alias OP=root
Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod
Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk
SYSADER SERS= SYDCMD,DSKCMD
DISKADER ALL=(OP) DSKCMD
sudo示例
?示例4
User_Alias ADMINUSER = adminuser1,adminuser2
Cmnd_Alias ADMINCMD = /usr/sbin/useradd,/usr/sbin/usermod,
/usr/bin/passwd [a-zA-Z], !/usr/bin/passwd root
ADMINUSER ALL=(root) NOPASSWD:ADMINCMD,
PASSWD:/usr/sbin/userdel
?示例5
Defaults:wang runas_default=tom
wang ALL=(tom,jerry) ALL
?示例6
wang 192.168.1.6,192.168.1.8=(root) /usr/sbin/,!/usr/sbin/useradd
?示例7
wang ALL=(ALL) /bin/cat /var/log/messages
sudo命令
?ls -l /usr/bin/sudo
?sudo –i –u wang 切换身份
?sudo [-u user] COMMAND
-V 显示版本信息等配置信息
-u user 默认为root
-l,ll 列出用户在主机上可用的和被禁止的命令
-v 再延长密码有效期限5分钟,更新时间戳
-k 清除时间戳(1970-01-01),下次需要重新输密码
-K 与-k类似,还要删除时间戳文件
-b 在后台执行指令
-p 改变询问密码的提示符号
示例:-p ”password on %h for user %p:”
PAM认证机制
?PAM相关文件
?模块文件目录:/lib64/security/.so
?环境相关的设置:/etc/security/
?主配置文件:/etc/pam.conf,默认不存在
?为每种应用模块提供一个专用的配置文件:/etc/pam.d/APPNAME
?注意:如/etc/pam.d存在,/etc/pam.conf将失效
pam认证原理
?PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam.so
?PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于
/etc/pam.d下),最后调用认证文件(位于/lib64/security下)进行安全认证
PAM认证机制
?PAM认证过程:
1.使用者执行/usr/bin/passwd 程序,并输入密码
2.passwd开始调用PAM模块,PAM模块会搜寻passwd程序的PAM相关设置文
件,这个设置文件一般是在/etc/pam.d/里边的与程序同名的文件,即PAM会
搜寻/etc/pam.d/passwd此设置文件
3.经由/etc/pam.d/passwd设定文件的数据,取用PAM所提供的相关模块来进
行验证
4.将验证结果回传给passwd这个程序,而passwd这个程序会根据PAM回传的
结果决定下一个动作(重新输入密码或者通过验证)
PAM认证机制
?通用配置文件/etc/pam.conf格式
application type control module-path arguments
?专用配置文件/etc/pam.d/ 格式
type control module-path arguments
?说明:
?服务名(application)
telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配
置的其它服务
?模块类型(module-type)
?control PAM库该如何处理与该服务相关的PAM模块的成功或失败情况
?module-path 用来指明本模块对应的程序文件的路径名
?Arguments 用来传递给该模块的参数
PAM认证机制
?模块类型(module-type)
?Auth 账号的认证和授权
?Account 与账号管理相关的非认证类的功能,如:用来限制/允许用户对某
个服务的访问时间,当前有效的系统资源(最多可以有多少个用户),限制用
户的位置(例如:root用户只能从控制台登录)
?Password 用户修改密码时密码复杂度检查机制等功能
?Session 用户获取到服务之前或使用服务完成之后需要进行一些附加的操作,
如:记录打开/关闭数据的信息,监视目录等
?-type 表示因为缺失而不能加载的模块将不记录到系统日志,对于那些不总是
安装在系统上的模块有用
以上是关于加密与安全部分 实验及知识点的主要内容,如果未能解决你的问题,请参考以下文章
《密码编码学与网络安全》William Stalling著---学习笔记知识点速过传统密码+经典对称加密算法+经典公钥密码算法+密码学Hash函数