前言:
去年学过一段时间的现代密码学, 最近在配置 github, Linux 主机之间建立信任关系的时候都用到了其中一些知识, 所以刚好整理一下, 想直接看操作方式的可直接拉到下面
密码学基本知识
一 现代密码学基本知识
现代密码学的分类:
对称密码体制 (传统密码体制)
非对称密码体制 (公钥密码体制)
现在密码学的基本原则:
实际上的安全 (虽然没有在理论上严格证明出来, 但经过许多人许多年的攻击并没有找到有效的攻击方法)
柯克霍夫原则 (密码系统的安全性不应该取决于不易改变的算法, 而应该取决于可随时改变的密钥)
二 对称密码体制的缺陷
密钥分配问题
通信双方要进行保密通信, 需要通过秘密的安全通道传送或协商加密密钥, 而这种安全通道在实际中很难实现
密钥管理问题
在有 N 个用户的通信网络中, 每个用户要想和其他 N-1 个用户进行通信, 必须使用 N-1 个密钥, 而系统中总的密钥数量将达到 n(n-1)/2 当 n 比较大时, 这样大的密钥量, 在生产和保存, 传递, 销毁等各个环节将变得复杂, 易存在安全隐患
数字签名问题
对称密码体制中通信双方拥有同样的密钥, 所以接收方可以伪造签名, 发送方也可以否认发送过某消息, 难于解决陌生人之间的身份认证和交易不可否认的问题
三 公钥密码体制加解密原型
发送方 A 查找接收方 B 的公钥
A 用公钥加密算法以 B 的公钥作为加密密钥对明文进行加密
A 通过不安全信道将密文发送给 B
B 收到密文后使用自己的私钥对密文解密还原成明文
四 RSA 加密算法及签名算法分析 (因为 linux ssh 登陆用的是 ssh 所以单独分析一下)
转自 http://www.zhihu.com/question/25912483/answer/31653639, 具体细节请移步大神的数学讲解
RSA 公钥加密体制包含如下 3 个算法: KeyGen(密钥生成算法),Encrypt(加密算法) 以及 Decrypt(解密算法)
其中公钥用于对数据进行加密, 私钥用于对数据进行解密当然了, 这个也可以很直观的理解: 公钥就是公开的密钥, 其公开了大家才能用它来加密数据私钥是私有的密钥, 谁有这个密钥才能够解密密文否则大家都能看到私钥, 就都能解密, 那不就乱套了
================= 分割线 =================
RSA 签名体制签名体制同样包含 3 个算法: KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法)
在签名算法中, 私钥用于对数据进行签名, 公钥用于对签名进行验证这也可以直观地进行理解: 对一个文件签名, 当然要用私钥, 因为我们希望只有自己才能完成签字验证过程当然希望所有人都能够执行, 大家看到签名都能通过验证证明确实是我自己签的
用公钥加密, 私钥解密 加密文件
用私钥加密, 用公钥解密 数字签名
Linux 两台主机之间建立信任关系
一般用 ssh 命令访问另一台机器, 或者用 scp 命令从别的机器拷贝数据和文件, 都要输入对应账户的密码而在两台机器之间建立信任关系, 则可以省略输入密码的过程
一 : 首先来分析一下口令登陆的过程:
(转自 http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html)
远程主机收到用户的登录请求, 把自己的公钥发给用户
用户使用这个公钥, 将登录密码加密后, 发送回来
远程主机用自己的私钥, 解密登录密码, 如果密码正确, 就同意用户登录
如果你是第一次登录对方主机, 系统会出现下面的提示:
- $ ssh user@host
- The authenticity of host 'host (12.18.429.21)' can't be established.
- RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
- Are you sure you want to continue connecting (yes/no)?
这段话的意思是, 无法确认 host 主机的真实性, 只知道它的公钥指纹, 问你还想继续连接吗?
所谓公钥指纹, 是指公钥长度较长 (这里采用 RSA 算法, 长达 1024 位), 很难比对, 所以对其进行 MD5 计算, 将它变成一个 128 位的指纹上例中是 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d, 再进行比较, 就容易多了
很自然的一个问题就是, 用户怎么知道远程主机的公钥指纹应该是多少? 回答是没有好办法, 远程主机必须在自己的网站上贴出公钥指纹, 以便用户自行核对
假定经过风险衡量以后, 用户决定接受这个远程主机的公钥
Are you sure you want to continue connecting (yes/no)? yes
系统会出现一句提示, 表示 host 主机已经得到认可
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然后, 会要求输入密码
Password: (enter password)
如果密码正确, 就可以登录了
当远程主机的公钥被接受以后, 它就会被保存在文件 $HOME/.ssh/known_hosts 之中下次再连接这台主机, 系统就会认出它的公钥已经保存在本地了, 从而跳过警告部分, 直接提示输入密码
每个 SSH 用户都有自己的 known_hosts 文件, 此外系统也有一个这样的文件, 通常是 / etc/ssh/ssh_known_hosts, 保存一些对所有用户都可信赖的远程主机的公钥
这里我认为采用的是 RSA 的加密和解密方案
二: 建立信任关系的过程
(转自 http://tobeyouth.github.io/2014/07/14/ssh-login.html)
假设现在有两台主机 A 和 B, 要在 B 上建立对 A 的信任, 需要先在 A 主机上生成 ssh-key 如果不清楚 A 主机是否已经有 ssh-key 了, 可以先执行:
ls ~/.ssh
看看. ssh 文件夹中是否存在 id_rsa,id_rsa.pub 这两个文件, 其中 id_rsa.pub 就是前面提到的公钥
如果之前没有生成过这两个文件, 那么需要执行:
ssh-keygen -t rsa
(在这里插个链接讲 ssh -keygen 各个参数含义的, 有兴趣的可移步
http://killer-jok.iteye.com/blog/1853451)
系统会弹出几个选项供选择, 如果没有特殊需要, 一路默认下去就行了, 最后会在~/.ssh 文件夹中生成我们所需要的 id_rsa 和 id_rsa.pub, 然后打印出 id_rsa.pub 看看
cat~ / .ssh / id_rsa.pub
接下来, 我们先不要关闭 A 主机, 在另一界面登录 B, 查看 B 的. ssh 文件夹下有没有 authorized_keys 这个文件, 如果没有的话, 需要新建一个:
vim authorized_keys
把刚才打印出的 A 主机的 id_rsa.pub 的内容添加到其中就可以了
至此, B 对 A 的信任关系就算建立上了, 可以在 A 主机上试试用 ssh 方式登录 B 看看, 这个时候如果不需要输入密码, 就证明信任关系已经建立成功了
注意因为 sshd 有严格的权限要求, 所以如果还需要输入密码的话, 可以到 B 主机看看. ssh 文件夹和 authorized_keys 文件的权限
.ssh 文件夹的权限应为 755,authorized_keys 文件的权限应为 600, 可以使用 chmod 命令来更改:
- chmod 755 ~/.ssh
- chmod 600 ~/.ssh/authorized_keys
私以为这个过程用的是 RSA 的数字签名的原理, 而并非加密解密原理, 或者是加密和签名组合在一起处理, 因为当 A 想要不需要密码便可以访问 B 的时候, 需要把 A 的公钥放在 B 的可信赖文件中, 当 A 直接 ssh B 的时候, B 会向用户 A 发送一段随机字符串, A 用自己的私钥加密后, 再发回来 B 用事先储存的公钥进行解密, 如果成功, 就证明用户 A 是可信的, 直接允许登录 shell, 不再要求密码
这与 RSA 数字签名算法的过程是吻合的, 所以认为原理应该是这样的
来源: http://blog.csdn.net/u014001964/article/details/51727390