博客

  • openssl配置

    参考:
    https://docs.openssl.org/3.4/man5/config/

    Views: 11

  • windows11上wsl或虚拟机端口映射

    # netsh interface portproxy add v4tov4 listenport=[win10端口] listenaddress=0.0.0.0 connectport=[虚拟机的端口] connectaddress=[虚拟机的ip]
    netsh interface portproxy add v4tov4 listenport=5201 listenaddress=0.0.0.0 connectport=5201 connectaddress=172.21.8.19
    netsh interface portproxy delete v4tov4 listenport=5201 listenaddress=0.0.0.0
    

    Views: 18

  • ubuntu安装ca证书

    sudo cp ca.crt /usr/local/share/ca-certificates
    sudo update-ca-certificates

    Views: 7

  • kms激活

    激活windows11企业版

    slmgr /skms 192.168.33.1
    #自动发现kms服务,也就是没有指定kms服务时的默认行为
    slmgr /ckms
    slmgr /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43
    slmgr /ato
    

    各版本系统的KMS Key

    https://learn.microsoft.com/zh-cn/windows-server/get-started/kms-client-activation-keys?tabs=server2025%2Cwindows1110ltsc%2Cversion1803%2Cwindows81

    激活office 2024

    cd Program Files\\Microsoft Office\\Office16
    cscript ospp.vbs /sethst:192.168.33.1  
    #移除kms主机恢复自动发现kms服务器
    cscript ospp.vbs /remhst
    cscript ospp.vbs /inpkey:XJ2XN-FW8RK-P4HMP-DKDBV-GCVGB
    cscript ospp.vbs /act
    

    Views: 20

  • 更换硬盘控制器后更新驱动

    硬换硬盘控制器有多种原因,虚拟机中修改硬盘配置,更换主板等
    用安装光盘启动电脑,安装的时候选择修复然后进入命令行,执行以下命令

    drvload D:\viostor\w10\amd64\viostor.inf
    dism /image:c:\ /add-driver /driver:d:\viostor\w10\amd64\viostor.inf
    

    然后重新启动系统就能找到硬盘控制器驱动了

    其中D盘是virtio驱动盘,C盘是原系统盘

    如果还启动不了再执行以下命令

    drvload D:\viostor\w10\amd64\viostor.inf
    bcdboot C:\Windows
    

    Views: 9

  • SSH握手过程

    SSH是一个古老的协议,最新的SSH2.0发布于2006年1月,已经近20年没有更新了(除了添加了新的加密算法)。
    SSH的安全性设计中规中矩,握手过程相当繁锁,一个报文只做一件事,协商一个参数,还要反复发送确认。

    这是华为知识百科上的握手过程,但这个是不完整的,把非关键的过程省略了,可能因为画全了太繁锁。

    握手

    下面是握手步聚:
    1. TCP三次握手
    一共3个报文
    2. 协商协议版本号
    一共2个报文(虽然图上是3个报文,但我抓包只有2个报文,没有确定版本协商的报文)
    3. 算法协商
    一共2个报文,是在Key Exchange Init消息中完成的,双方各种发送自己支持的算法列表。然后在列表中从前到后选择第1个双方都支持的算法。这里发送方和接收方应该是可以选择不同的算法,用这个选择法根本没法保证选择的算法一致。
    参考RFC4253第7章,算法协商是按如下规则进行的:
    对于加密和MAC算法在每个方向上是可以不同的,可以选择双方各自的首选算法作为对应方向的加密和MAC算法,对于AEAD加密,MAC算法协商是忽略的。
    密钥交换算法因为必须双方一致才能进行,所以优先以客户端首选算法为准。
    服务器公钥签名算法只要双方都支持就行,DH KE Reply报文中会返回一个具体的服务器签名算法/公钥算法及其公钥和签名结果。服务器上通常会有多个公钥,这些公钥保存在/etc/ssh/*.pub
    4. 密钥交换
    对于ECDH/ED25519交换来说一共需要3个报文,传统DH算法则需要6个报文,两个用于交换公钥和随机数,最后还有一个New Keys报文用于确认交换成功(如果算法协商时没有协商一致的交换算法就会交换失败)。
    5. 认证
    对于公钥认证是2个报文,客户端用私钥对公钥以及前面的报文,用户身份信息等进行签名。服务器用公钥对签名进行验证,认证通过返回认证成功的报文。
    6. 会话请求
    2个报文,用于开始会话数据传输,下面就可以命令交互了。
    以上一共用掉了17个报文了。

    rekey,重协商,PFS

    RFC4253建议每个小时或传输1GB的数据就要重新握手来实现PFS,重新握手包含了算法协商和密钥交换两个步聚共5个报文。握手是在Transport层进行的,而且是加密的。
    RFC4253并没有说明如何在rekey的过程中不丢包,但要实现不丢包只有采取下述办法:
    – 所有数据包按顺序到达,这个由TCP来保证
    – 收到对方的New Keys报文后只切换这个方向的密钥,也就是两个方向的密钥不是同时切换的。
    OpenSSH中是通过RekeyLimit参数配置rekey的,但是默认没有开启。

    服务器公钥签名

    服务器公钥是保存在/etc/ssh/目录的,用服务器私钥对服务器公钥和服务器标识信息(可能就是IP地址)进行签名,然后客户端用服务器的公钥进行验签。服务器的公钥是和签名一起在DH KE Reply报文中发送过来的,用户需要自行判断是否信息服务器的公钥。信任的服务器公钥保存在~/.ssh/known_hosts文件中。
    服务器公钥签名是与密钥交换一起进行的,不需要额外的数据包。
    有些SSH客户端会要求提前信息SSH服务器公钥,比如github就是如此,而且github公示了它的公钥信息以方便进行信息。
    以下是github的公钥信息
    https://docs.github.com/zh/enterprise-cloud@latest/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
    自己的公钥指纹可以用以下命令查看:
    ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub -E sha256
    对服务器公钥进行信任可以避免中间人攻击。
    参考:
    http://walkerdu.com/2019/10/24/ssh/
    https://segmentfault.com/a/1190000011395818
    https://datatracker.ietf.org/doc/rfc4253/
    https://datatracker.ietf.org/doc/rfc4251/
    https://datatracker.ietf.org/doc/rfc4252/
    https://datatracker.ietf.org/doc/rfc4344/
    https://datatracker.ietf.org/doc/rfc5656/
    https://datatracker.ietf.org/doc/html/rfc8731
    https://datatracker.ietf.org/doc/rfc4419/

    Views: 19

  • Wireguard的密钥协商/握手

    Wireguard只使用2个报文1个RTT就能完成密钥协商和身份认证,这使Wireguard的连接速度更快,而且能更好的防护DOS攻击(验证不通过不回报文)。
    Wireguard也是支持PFS的,所以每隔REKEY_AFTER_TIME(120s)就重新执行一次密钥协商/握手,这与第一次握手并没有什么不同。
    每经过KEEPALIVE时间,且这段时间没有消息发送则发送一个空的报文,如果再经过REKEY_TIMEOUT(5s)没有收到数据包则发起新的握手。
    经过REJECT_AFTER_TIME(180s) * 3后没有收到数据包则会话密钥过期,断开连接。
    为了抵抗抗拒绝服务攻击握手包需要推带MAC字段,MAC的密钥为对方的公钥,所以wireguard公钥也要保护好。
    wireguard状态中的上次握手时间指的就是上次密钥协商/握手的时间,是固定2分钟执行一次,REJECT_AFTER_TIME(180s) * 3后没有重新握手连接就中断了。起初我还以为这个握手时间是上次发包的时间。

    握手过程

    带cookie的握手过程

    第1个包

    第2个包

    cookie应答包

    负载包

    wireguard一共定义了这4个包类型,没有连接关闭包。

    wireguard各个常量的值:
    https://github.com/torvalds/linux/blob/master/drivers/net/wireguard/messages.h
    wireguard协议参考:
    https://www.wireguard.com/protocol/
    https://www.wireguard.com/papers/wireguard.pdf

    Views: 17

  • IKEv2中的DH密钥交换和PFS

    很多资料都没有清晰的禅述IKE中PFS的实现原理,这里结合IKE密钥交换过程说明IPSec中PFS的实现。
    IKEv2的SA协商分为三个过程,分别是IKE_SA_INIT,IKE_AUTH,CREATE_CHILD_SA。

    IKE_SA_INIT和IKE_AUTH是合在一起的,前两个包完成DH密钥交换和IKE SA生成,后两个包完成认证和IPSec SA生成,这里认证和协商IPSec的包是合在一起的。
    IKE_SA_INIT过程只能生成一个IPSec SA,如果有多个IPSec SA需要生成则要执行CREATE_CHILD_SA过程。

    CREATE_CHILD_SA过程只有两个数据包,其中DH公钥(就是KEi和KEr)是可选的,当开启PFS时每个CREATE_CHILD_SA过程都要包含DH公钥。
    当IKE SA和IPSec SA将要过期时需要执行CREATE_CHILD_SA创建新的等效SA替换旧的SA,新的SA创建完成后删除旧的SA。如果是基于更新密钥的原因执行CREATE_CHILD_SA需要携带REKEY_SA类型的Notify负载(记为N(REKEY_SA)。其中IKE SA的rekey协商必须要包含DH公钥(KEi,KEr)的,不管是否开启PFS(RFC 7296 2.18节)。
    以下为用于rekey的CREATE_CHILD_SA过程

    知识点:
    IKE的DH交换是互相的,需要交换两个DH公钥,同时也会生成两个共享密钥,一个用于加密发出的流量,一个用于解密收到的流量。
    IKEv1和IKEv2的区别

    参考:
    IKEv2
    https://datatracker.ietf.org/doc/rfc7296/
    IKEv2协议详解
    https://cshihong.github.io/2019/04/09/IPSec-VPN%E4%B9%8BIKEv2%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/
    量子安全密码
    https://datatracker.ietf.org/doc/rfc9370/

    Views: 7

  • RSA加密/签名模式(填充方式)

    填充是PKCS#1的主要内容,占了正文三分之二的篇幅
    早期的填充方式称为RSA-PKCS#1 v1.5填充,这种填充方式只是生成一个随机数与明文连接在一起,相对不安全,后来在RSA-PKCS#1 v2.1中(也就是RFC3447)定义了OAEP(用于加密)和PSS(用于签名)两种填充方式,新的填充方式使用MGF基于随机数对明文进行掩码处理。建议使用OAEP和PSS填充而不是RSA-PKCS#1 v1.5填充。

    MGF: 掩码生成函数

    https://datatracker.ietf.org/doc/rfc8017/
    RSA-PKCS#1 v2.2
    https://datatracker.ietf.org/doc/rfc3447/
    RSA-PKCS#1 v2.1

    Views: 35