SIP REG Digest认证算法分析
一、回顾SIP Register的认证过程
- Client(通常是话机)向REG Server(一般是OpenSIPS或Freeswitch)发起REGISTER注册请求(注:此时发送的请求里,只有一些用户名、客户端类型之类的普通信息)
- REG Server收到请求后,发现里面没有Digest等安全相关的摘要信息,直接返回401(未授权),同时会附加额外的安全信息(比如:realm/nonce/algorithm/qop)
- Client收到401拒绝返回后,根据服务端返回的realm/nonce/algorithm/qop信息,结合自己的password,计算出一个最终的response digiest(注:是一个md5值),重新发起第2次REGISTER,并附带上response digest等认证相关信息。
- REG Server根据Client发过来的Authorization认证信息进行校验,如果校验通过,则返回200 OK,认证通过
二、认证过程中的SIP信令(报文)
这里介绍二种查看REGISTER过程SIP信令的方法:
2.1 打开FreeSwitch的SIP trace功能
sofia profile internal siptrace on|off
在FreeSwitch控制台中,输入上面的命令行(on为打开,off为关闭),然后用Client(比如:免费开源软电话MicroSIP)注册,此时FreeSwitch中会输出4段SIP报文,分别对应认证过程中的4个阶段,类似下面这样:
第1段 REGISTER(Client → FreeSwitch)
recv 647 bytes from tcp/[10.32.26.25]:51696 at 02:14:58.914917:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:51696;rport;branch=z9hG4bKPj8d4db68b24754f539dbf3b563a44fe55;alias
Max-Forwards: 70
From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60
To: <sip:1000@10.32.26.25>
Call-ID: 1e7af0e67a5044658fc7f6716d329642
CSeq: 36850 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0
第2段 401 Unauthorized(FreeSwitch → Client)
send 670 bytes to tcp/[10.32.26.25]:51696 at 02:14:58.918913:
------------------------------------------------------------------------
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TCP 10.32.26.25:51696;rport=51696;branch=z9hG4bKPj8d4db68b24754f539dbf3b563a44fe55;alias
From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60
To: <sip:1000@10.32.26.25>;tag=Q0m1g96BS3vpa
Call-ID: 1e7af0e67a5044658fc7f6716d329642
CSeq: 36850 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", algorithm=MD5, qop="auth"
Content-Length: 0
第3段 REGISTER (第2次 Client → FreeSwitch)
recv 921 bytes from tcp/[10.32.26.25]:51696 at 02:14:58.925916:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:51696;rport;branch=z9hG4bKPj414de93b6fd34f21a9c453d81117fee2;alias
Max-Forwards: 70
From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60
To: <sip:1000@10.32.26.25>
Call-ID: 1e7af0e67a5044658fc7f6716d329642
CSeq: 36851 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001
Content-Length: 0
第4段 200 Ok(FreeSwitch → Client)
send 646 bytes to tcp/[10.32.26.25]:51696 at 02:14:58.933914:
------------------------------------------------------------------------
SIP/2.0 200 OK
Via: SIP/2.0/TCP 10.32.26.25:51696;rport=51696;branch=z9hG4bKPj414de93b6fd34f21a9c453d81117fee2;alias
From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60
To: <sip:1000@10.32.26.25>;tag=r9Dtj4QFpcK9N
Call-ID: 1e7af0e67a5044658fc7f6716d329642
CSeq: 36851 REGISTER
Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;expires=300
Date: Mon, 06 Sep 2021 02:14:58 GMT
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0
2.2 采用WireShark抓包
参考上图,启动WireShark,指定网卡以及抓包的协议为sip后,本机用Client注册登录1次,就能抓到这4个阶段的SIP信令(注:上图的REG Server是OpenSIPS),跟FreeSwith做为REG Server对比,可以发现OpenSIPS第3阶段,返回的Authorization里,少了cnounce、 qop、nc这3个值,这一点要注意一下。
三、Response Digest的计算过程
通过观察SIP报文发现,整个注册过程中Client始终没有发送过任何password的明文,相对还是很安全的。Client第2次发起REGISTER时,附带的Response值是关键!REG Server将校验这个值的正确性,校验通过才会注册成功。
整个计算过程,分成三步:
3.1 计算HA1
规则如下:
algorithm
|
HA1
|
---|---|
MD5(或未指定) |
MD5(username:realm:password) |
MD5-sess |
MD5(MD5(username:realm:password):nonce:cnonce) |
- 注:MD5计算出来的值为32位小写,password为密码,只有Client自己知道。
例1(FreeSwitch充当REG Server):
Client第2次提交的REGISTER请求中,Authorization信息为:
Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001
则HA1 = MD5("1000:10.32.26.25:1234") = 6a5e40ec8a6cbac75b9914b271516a47 (假设password为1234)
例2(OpenSIPS充当REG Server):
第2阶段,FreeSwitch返回的Authorization如下:
Authorization: Digest username="440444", realm="10.2.60.171", nonce="6135e48401ea0109021093850f9c5db2bf101786", uri="sip:10.2.60.171:5060", response="885f45ae2179c9d8ce2bc1cbd8e4bb9f"
则HA1 = MD5("440444:10.2.60.171:440444") = 109cf921db79c57e146cd8d46429312d (假设password与username相同,都为440444)
3.2 计算HA2
规则如下:
qop
|
HA2
|
---|---|
auth(或未指定) |
MD5(method:digestURI) |
auth-int |
MD5(method:digestURI:MD5(entityBody)) |
注:digestURI为SIP信令Authorization节点中的uri值,对于注册来说,method即为固定值REGISTER
例1(FreeSwitch充当REG Server):
Client第2次提交的REGISTER请求中,Authorization信息为:
Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001
则HA2 = MD5("REGISTER:sip:10.32.26.25:5070;transport=tcp") = c0a1637fb943febd38e69c2087d58fe9
例2(OpenSIPS充当REG Server):
第2阶段,FreeSwitch返回的Authorization如下:
Authorization: Digest username="440444", realm="10.2.60.171", nonce="6135e48401ea0109021093850f9c5db2bf101786", uri="sip:10.2.60.171:5060", response="885f45ae2179c9d8ce2bc1cbd8e4bb9f"
则HA2 = MD5("REGISTER:sip:10.2.60.171:5060") = 9f5c90dad45f8b57a9de5ad977027d7b
3.3 计算Response
根据前2步计算出来的HA1及HA2,计算response值,规则如下:
qop
|
response
|
---|---|
未指定 |
MD5(HA1:nonce:HA2) |
auth或auth-int |
MD5(HA1:nonce:nonceCount:cnonce:qop:HA2) |
计算结果如下:
|
例1(FreeSwitch充当REG Server)
|
例2(OpenSIPS充当REG Server)
|
---|---|---|
response |
MD5("6a5e40ec8a6cbac75b9914b271516a47:bee3366b-cf59-476e-bc5e-334e0d65b386:00000001:c3606b3f70544096a7e17fcdb4670795:auth:c0a1637fb943febd38e69c2087d58fe9") =7a8049557b2e77602625fa9ee7d8f088 |
MD5("109cf921db79c57e146cd8d46429312d:6135e48401ea0109021093850f9c5db2bf101786:9f5c90dad45f8b57a9de5ad977027d7b") =885f45ae2179c9d8ce2bc1cbd8e4bb9f |
qop | auth | 无 |
nonceCount | 00000001 | 无 |
nonce | bee3366b-cf59-476e-bc5e-334e0d65b386 | 6135e48401ea0109021093850f9c5db2bf101786 |
HA2 | c0a1637fb943febd38e69c2087d58fe9 | 9f5c90dad45f8b57a9de5ad977027d7b |
HA1 | 6a5e40ec8a6cbac75b9914b271516a47 | 109cf921db79c57e146cd8d46429312d |
cnonce | c3606b3f70544096a7e17fcdb4670795 | 无 |
附1:话机注销过程,其中跟注册过程几乎完全一样,只是Expires值会设置为 0,交互报文如下:
recv 547 bytes from tcp/[10.32.26.25]:61932 at 09:21:34.274829:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:61932;rport;branch=z9hG4bKPj909d767a192f4db1ad491cb466fe9b99;alias
Max-Forwards: 70
From: <sip:1099@10.32.26.25>;tag=c40977782b0d4b87912ff9636fdce333
To: <sip:1099@10.32.26.25>
Call-ID: a08b443e427044e8815ed2e3f1dd51d0
CSeq: 23519 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1099@10.32.26.25:61932;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 0
Content-Length: 0 ------------------------------------------------------------------------
send 670 bytes to tcp/[10.32.26.25]:61932 at 09:21:34.279829:
------------------------------------------------------------------------
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TCP 10.32.26.25:61932;rport=61932;branch=z9hG4bKPj909d767a192f4db1ad491cb466fe9b99;alias
From: <sip:1099@10.32.26.25>;tag=c40977782b0d4b87912ff9636fdce333
To: <sip:1099@10.32.26.25>;tag=6e3DjUDX76p3N
Call-ID: a08b443e427044e8815ed2e3f1dd51d0
CSeq: 23519 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="10.32.26.25", nonce="7ff40180-f465-465c-8ca1-44c77d2107f4", algorithm=MD5, qop="auth"
Content-Length: 0 ------------------------------------------------------------------------
recv 821 bytes from tcp/[10.32.26.25]:61932 at 09:21:34.279829:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:61932;rport;branch=z9hG4bKPj793d3c194cd6461589e44c864e031e52;alias
Max-Forwards: 70
From: <sip:1099@10.32.26.25>;tag=c40977782b0d4b87912ff9636fdce333
To: <sip:1099@10.32.26.25>
Call-ID: a08b443e427044e8815ed2e3f1dd51d0
CSeq: 23520 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1099@10.32.26.25:61932;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 0
Authorization: Digest username="1099", realm="10.32.26.25", nonce="7ff40180-f465-465c-8ca1-44c77d2107f4", uri="sip:10.32.26.25:5070;transport=tcp", response="92e6ae0a0f23e04d21b0866a7746decd", algorithm=MD5, cnonce="85b6265e67b949aa9c2c7bcc26cad2c9", qop=auth, nc=00000001
Content-Length: 0 ------------------------------------------------------------------------
send 578 bytes to tcp/[10.32.26.25]:61932 at 09:21:34.286827:
------------------------------------------------------------------------
SIP/2.0 200 OK
Via: SIP/2.0/TCP 10.32.26.25:61932;rport=61932;branch=z9hG4bKPj793d3c194cd6461589e44c864e031e52;alias
From: <sip:1099@10.32.26.25>;tag=c40977782b0d4b87912ff9636fdce333
To: <sip:1099@10.32.26.25>;tag=7Qv6Kpy04FDpH
Call-ID: a08b443e427044e8815ed2e3f1dd51d0
CSeq: 23520 REGISTER
Date: Thu, 23 Sep 2021 09:21:34 GMT
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0 ------------------------------------------------------------------------
附2:如果注册过程中,digest校验失败,SIP会返回403,报文如下
recv 647 bytes from tcp/[10.32.26.25]:63125 at 09:26:04.493306:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:63125;rport;branch=z9hG4bKPj258fc605159e449ea95e1fdd55b4c16d;alias
Max-Forwards: 70
From: <sip:1099@10.32.26.25>;tag=69516ebac8224d94a7225271fec56f87
To: <sip:1099@10.32.26.25>
Call-ID: 514ac58ec6dd4d8295a62d8f04648c52
CSeq: 25348 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1099@10.32.26.25:63125;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0 ------------------------------------------------------------------------
send 670 bytes to tcp/[10.32.26.25]:63125 at 09:26:04.496305:
------------------------------------------------------------------------
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TCP 10.32.26.25:63125;rport=63125;branch=z9hG4bKPj258fc605159e449ea95e1fdd55b4c16d;alias
From: <sip:1099@10.32.26.25>;tag=69516ebac8224d94a7225271fec56f87
To: <sip:1099@10.32.26.25>;tag=DemUyr3NK5j6p
Call-ID: 514ac58ec6dd4d8295a62d8f04648c52
CSeq: 25348 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
WWW-Authenticate: Digest realm="10.32.26.25", nonce="7180f42a-1d76-4a6f-a846-6f9b34f7db4e", algorithm=MD5, qop="auth"
Content-Length: 0 ------------------------------------------------------------------------
recv 921 bytes from tcp/[10.32.26.25]:63125 at 09:26:04.496305:
------------------------------------------------------------------------
REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.32.26.25:63125;rport;branch=z9hG4bKPj6727ace0eb4d406cadf969591438a644;alias
Max-Forwards: 70
From: <sip:1099@10.32.26.25>;tag=69516ebac8224d94a7225271fec56f87
To: <sip:1099@10.32.26.25>
Call-ID: 514ac58ec6dd4d8295a62d8f04648c52
CSeq: 25349 REGISTER
User-Agent: MicroSIP/3.20.3
Supported: outbound, path
Contact: <sip:1099@10.32.26.25:63125;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>"
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Authorization: Digest username="1099", realm="10.32.26.25", nonce="7180f42a-1d76-4a6f-a846-6f9b34f7db4e", uri="sip:10.32.26.25:5070;transport=tcp", response="ba8664d44668c11d030a9436800338e7", algorithm=MD5, cnonce="4c02d90a0bf94ae28a1ecd8cf30b126e", qop=auth, nc=00000001
Content-Length: 0 ------------------------------------------------------------------------
send 548 bytes to tcp/[10.32.26.25]:63125 at 09:26:04.499309:
------------------------------------------------------------------------
SIP/2.0 403 Forbidden
Via: SIP/2.0/TCP 10.32.26.25:63125;rport=63125;branch=z9hG4bKPj6727ace0eb4d406cadf969591438a644;alias
From: <sip:1099@10.32.26.25>;tag=69516ebac8224d94a7225271fec56f87
To: <sip:1099@10.32.26.25>;tag=eQDm0KmSge9rj
Call-ID: 514ac58ec6dd4d8295a62d8f04648c52
CSeq: 25349 REGISTER
User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0 ------------------------------------------------------------------------
参考文章:
https://en.wikipedia.org/wiki/Digest_access_authentication
https://datatracker.ietf.org/doc/html/rfc2069
https://datatracker.ietf.org/doc/html/rfc2617
SIP REG Digest认证算法分析的更多相关文章
- http 登录Digest认证相关知识
Digest access authentication https://en.wikipedia.org/wiki/Digest_access_authentication Digest acces ...
- sip鉴权认证算法详解及python加密
1. 认证和加密 认证(Authorization)的作用在于表明自己是谁,即向别人证明自己是谁.而相关的概念是MD5,用于认证安全.注意MD5仅仅是个hash函数而已,并不是用于加密.因为ha ...
- 批量检测GoAhead系列服务器中Digest认证方式的服务器弱口令
最近在学习用python写爬虫工具,某天偶然发现GoAhead系列服务器的登录方式跟大多数网站不一样,不是采用POST等方法,通过查找资料发现GoAhead是一个开源(商业许可).简单.轻巧.功能强大 ...
- HTTP Basic和Digest认证介绍与计算
一.说明 web用户认证,最开始是get提交+把用户名密码存放在客户端的cookie中的形式:在意识到这样不安全之后逐渐演变成了post提交+把用户凭证放到了服务端的session中的形式(当然ses ...
- 【ASP.NET Web API2】Digest认证
Digest摘要认证 对于Basic认证方案来说,被传输的认证凭证仅仅采用Base64编码,所以包含密码的认证凭证基本上可以视为明文传输.Digest认证在此基础上进行了改善,在一定程度上提高了安全系 ...
- Http Digest认证协议
转自:http://blog.csdn.net/htjoy1202/article/details/7067287 其认证的基本框架为挑战认证的结构,如下图所示: 1.客户端希望取到服务器上的某个资源 ...
- SIP 认证
理解SIP的认证 1. 认证和加密 认证(Authorization)的作用在于表明自己是谁,即向别人证明自己是谁.而相关的概念是MD5,用于认证安全.注意MD5仅仅是个hash函数而已,并不是 ...
- SIP 认证方式
SIP认证是继承了HTTP的认证方式.HTTP的认证方案主要有Basic Authentication Scheme和Digest Access Authentication Scheme两种.而Ba ...
- Digest Authentication 摘要认证
“摘要”式认证( Digest authentication)是一个简单的认证机制,最初是为HTTP协议开发的,因而也常叫做HTTP摘要,在RFC2671中描述.其身份验证机制很简单,它采用杂凑式(h ...
- sip 认证分析
转自:http://blog.csdn.net/wangqi0079/article/details/11569489 SIP类似Http协议.其认证模式也一样.Http协议(RFC 2616 )规定 ...
随机推荐
- 用AI开发AI翻译助手:初学者也能轻松做出第一个应用
在过去,学习编程往往意味着大量阅读文档.理解晦涩的语法.查找资料,甚至要面对一个接一个的报错信息,这对初学者来说常常是一个令人望而生畏的过程.但在AI时代,这一切都变得不一样了. 我最近完成了一个小项 ...
- Java实现minio上传文件加解密操作
一.背景与需求 在云存储场景中,数据安全是核心需求之一.MinIO作为高性能对象存储服务,支持通过客户端加密(CSE)在数据上传前完成加密,确保即使存储服务器被攻破,攻击者也无法获取明文数据.本文将详 ...
- Vue3 学习-初识体验-helloworld
在数据分析中有一个最重要的一环就是数据可视化, 数据报表的开发. 从我从业这几年的经历上看, 经历了从业务系统导表格数据, 到Excel+PPT, 再是开源报表工具, 再是主流商业BI产品(低/零代码 ...
- 知识蒸馏 -- 定位蒸馏LD
定位蒸馏 定位蒸馏:Localization Distillation,简称LD 论文地址: Localization Distillation for Dense Object Detection ...
- SpringBoot3整合SpringSecurity6(四)添加用户、密码加密
写在前面 还记得在之前的文章中,我们在user表中手动插入了3条数据吗? 当时,大家就会有疑问.这一串密码是怎么来的呢,我们为啥要对密码进行加密? 带着这些疑问,我们继续上路.我们在开发一个应用系统, ...
- 使用Flask和OpenAI构建实时AI聊天应用
在当今AI技术迅速发展的时代,将AI能力集成到Web应用中已成为一种趋势.本文将分享我如何使用Flask框架和OpenAI API构建一个实时聊天应用,让用户可以与AI助手"Melon&qu ...
- Nohup 启动程序未指定输出日志,导致磁盘空间被占满的解决方案
1. 问题原因 当使用 nohup 启动程序时,默认情况下,标准输出(stdout)和标准错误(stderr)都会被重定向到 nohup.out 文件.例如: nohup python my_scri ...
- win10系统 wsappx消耗内存导致死机
问题描述:win10系统开机后,wsappx内存占用率一路飙升,直至电脑蓝屏,手动kill后,过一会死灰复燃. 问题解决:win+R输入 regedit 跳转注册表编辑器,找到 HKEY_LOCAL_ ...
- 转-Linux mpstat命令入门-CPU实时监控详解
简介 mpstat 来自Multiprocessor Statistics的英文缩写,是实时系统监控工具,主要用来查看多CPU系统中每个CPU的负载是否均衡,相关统计信息存放在/proc/stat ...
- 【2020.11.30提高组模拟】删边(delete) 题解
[2020.11.30提高组模拟]删边(delete) 题解 题意简述 给一棵树删边,每次删的代价为这条边所连的两个点的子树中最大点权值. 求删光的最小代价. \(n\le100000\). Solu ...