SSL/TLS_regedit tls_aes_256_gcm_sha384-程序员宅基地

技术标签: SSL/TLS  非对称加密  对称加密  

你可以带着以下目的进行学习:

  1. TLS Handshake握手发生了什么?
  2. 为什么需要握手?
  3. TLS使用什么加密算法来保护数据?
  4. 为什么我们需要数字证书?
  5. 为什么需要由证书颁发机构签名?
  6. 什么是数字签名,如何生成?

一、SSL/TLS

SSL:安全套接字层(Secure Socket Layer),是TLS的前身。
TLS:安全传输层协议的简称(Transport Layer Security)。

1.1 历史发展

SSL/TLS的历史
历史发展时间线如上图所示。

1995年由Netscape发布 SSL 2.0
1996年由Netscape发布 SSL 3.0
1999年由IETF在RFC 2246中首次定义 TLS 1.0,作为SSL 3.0的升级
2006年由IETF在RFC 4346发布 TLS 1.1
2008年由IETF在RFC 5246发布 TLS 1.2
2018年由IETF在RFC 8446发布 TLS 1.3
2011年弃用 SSL 2.0
2015年弃用 SSL 3.0
2020年弃用 TLS 1.0 与 TLS 1.1

截至2020年,只有TLS 1.2TLS 1.3仍然有效。

1.2 使用场景

举三个生活中常用的示例:

  1. 网站 HTTPS 协议(HTTPS = HTTP + TLS)
  2. 邮箱 SMTPS 协议(SMTPS = SMTP + TLS)
  3. 安全文件传输 FTPS 协议(FTPS = FTP + TLS)

1.3 解决的问题

TLS 为我们解决了 3 件事:

  1. 认证(Authentication):TLS借助非对称密码学验证通信方的身份,这里指客户端与服务器。以此保证我们将访问真实的网站,而不是假网站。
  2. 保密(Confidentiality):TLS通过使用对称加密算法对消息加密,保护交换的数据免受未经授权的访问。
  3. 诚信(Integrity):TLS通过检查消息验证码识别传输期间的任何数据更改

1.4 工作流程

TLS工作方式
如上图所示,TLS工作流程由2个阶段(或2个协议)组成:

1、握手协议(Handshake protocol),其主要目的是进行身份验证和密钥交换,该阶段主要涉及以下步骤:

  • 协商 TLS 协议版本。
  • 选择密码算法或密码套件。
  • 通过非对称密钥相互认证。
  • 建立一个将用于下一阶段的共享密钥(对称加密密钥)。

2、记录协议(Record protocol),其主要目的是确保消息传输的机密性和完整性,该阶段主要涉及以下步骤:

  • 使用握手中建立的共享密钥对发出的消息进行加密。
  • 将加密后的消息传输到另一侧。
  • 验证消息是否在传输过程中进行了修改。
  • 使用握手中建立的共享密钥对接收的消息进行解密。

由于客户端与服务器大量的数据加解密交换发生在记录协议阶段,故又因该阶段解密数据量很大,又称该阶段为批量加密

可以看出,TLS在整个流程中同时使用了对称和非对称加密两种方式,那为什么不只使用一个?

  1. 对称密钥无法提供身份验证。对称密钥使得客户端和服务器之间共享一个相同的密钥,故他们彼此之间一无所知。而由于彼此之间不知道对方身份,故无法保证密钥的不泄露。
  2. 其实非对称加密都能满足以上需求。但是它比对称加密要慢很多,所谓“很多”,是指速度降低100倍至10000倍,因此,它显然不适用于批量加密。

在介绍SSL/TLS的完整握手流程之前,我们先了解下对称加密与非对称加密的相关内容,关于SSL/TLS的完整握手流程将在第四个大标题中讲解。

二、对称加密(Symmetric Cryptography)

2.1 工作原理

对称加密
(如上图所示)首先,Alice有一条纯文本消息,她想发送给Bob,但不希望互联网中的任何人都可以阅读。因此她使用他们之前彼此共享过的共享密钥(Shared secret key)对消息进行加密,然后通过互联网将加密的消息发送给Bob,Bob收到加密的消息后,他可以轻松的使用相同的密钥对其进行解密。由于该密钥用于加密和解密,且加密和解密的过程是对称的,故称该过程为对称加密过程。

似乎加密的数据就很安全?黑客仍然可以采用翻转攻击的方式破坏加密后的数据。

2.2 翻转攻击

翻转攻击
(如上图所示)现在,有一个可以在互联网上捕获他们交流信息的黑客Harry。但是,该消息已被加密,而Harry没有密钥,因此他将无法对其解密。但是他仍然可以改变消息,通过一种称为翻转攻击的技术。假设这一次,Alice不是在跟Bob通信,而是在和她的网上银行通信,此时Alice想转账$100给某人,该消息通过密钥进行加密后通过互联网发送给银行。此时,Harry捕获到了加密的消息,虽然他无法解密,但是他可以将某些位从1翻转为0,从0翻转为1,然后将修改后的消息转发到银行,当银行解密后将获得不同的消息内容,在这种情况下,转账金额变成了$900而不是$100,因此非常危险。

那么,这就是需要我们在收到加密的数据后,有方法确保加密的消息在传输过程中未被更改。该如何确保呢?使用认证加密

2.3 认证加密(Authentication Encryption)

认证加密包括对消息的加密验证过程。
身份验证加密
(如上图所示)该指示的是加密的过程,该过程可分为两个步骤,其一是对消息的加密,其二是为加密信息生成消息认证码

  1. 消息的加密:Alice的消息使用加密算法(Encryption Algotithm)进行加密,例如AES-256-GCM或CHACHA20,该加密算法同时会将共享密钥、随机数与一个初始化向量(initialization vector)作为输入,然后输出加密后的内容(Encrypted message)。
  2. 生成消息认证码:加密的内容、共享密钥和随机数作为MAC(Message Authentication Code 消息认证码)算法的输入,若使用AES-256-GCM作为加密算法,则认证算法为GMAC;若使用CHACHA20为加密算法,则认证算法为POLY1305。此MAC算法的作用类似于哈希函数,其输出是一个消息认证码(ae6f21b),即MAC,该MAC将伴随加密的内容一起发送给Bob。有时又称MAC为一个认证标签

AEAD
(如上图所示)在TLS 1.3中,除了加密的消息外,我们还想验证一些关联数据(Associated Data),例如地址(addresses)、端口(ports)、协议版本(protocol version)或序列号(sequence number),这些信息是未加密,且通信双方均知晓的 。在TLS 1.3中,将这些关联数据也作为MAC算法的输入,因此,整个过程又称为带有关联数据的认证加密(Authenticated Encryption with Associated Data,简称AEAD

接下来我们将看到Bob如何验证加密的消息在传输过程中是否被更改。
验证
(如上图所示)这是一个加密的反向过程。
从带有MAC的加密消息开始,我们将从加密的消息中经过提取(Untag)过程,获的MAC(ae6f21b)和不带有MAC的加密消息。然后,加密的消息、共享密钥、随机数(注意该随机数和加密过程中的随机数相同,在将消息发送给对方时,会将随机数填充到加密的消息中)以及关联数据作为MAC算法的输入,然后输出一个新的MAC值。现在,Bob可以简单地比较两个MAC值,如果它们不同,则表示加密的消息已被更改,否则,他可以安全地解密内容,并充分相信这与Alice发送的消息相同。

但是,Bob和Alice如何在不泄露给公众的情况下实现共享密钥的交换?
在这里插入图片描述
(如上图所示)为此,他们需要使用一种能够生成共享密钥的密钥建立协议,例如Diffie-Hellman Ephemeral(DHE)或Elliptic Curve Diffie-Hellman Ephemeral(ECDHE)。

接下来我们了解下Diffie-Hellman在密钥交换中的工作原理。

2.4 Diffie-Hellman

Diffie-Hellman
(如上图所示)首先基数 g模数 p,这两个数字是众所周知的,且Bob和Alice都知晓这两个数字。其次Bob和Alice都拥有一个私钥,Alice的私钥是 a,Bob的私钥是 b。准备就绪后,现在开始进行密钥交换:

  1. Alice通过私钥 a 计算出她的公钥A(通过如图的公式),同理,Bob计算出他的公钥 B
  2. Bob将B发送给Alice,Alice将A发送给Bob。
  3. Alice通过收到的B,结合私钥a和模数p计算出一个值S。此时Bob也由收到的A和自身的私钥b及模数p计算出一个值,而该值正好也等于S。这两个值神奇的相等!为什么?我们通过公式分解后可以发现他们的计算公式是相同的。

因此,Alice和Bob具有了相同的密钥S,而没有将其泄露给公众。

但是请记住,不同加密算法输出的密钥长度是不相同的。因此,Alice和Bob必须使用相同的密钥派生函数制作密钥,输出相同长度的密钥S。在TLS 1.3中,使用的密钥派生函数是HMAC-based key derivation function,所以这是为什么命名HKDF的原因。

让接下来我们将进一步了解密钥派生函数工作原理。

2.5 KDF

密钥派生函数(Key Derivation Function),简称KDF
密钥派生函数
(如上图所示)通常,KDF需要五个输入参数:

  1. 密钥内容(input key material,简称IKM),在我们的示例中,IKM是字母S
  2. 需要输出密钥的长度(Key Length),例如128位。
  3. 加密哈希函数(Hash Function),例如HMAC-SHA256。
  4. 可选信息(Optional Info),例如上下文(context)、应用的特定信息(app-specific)。
  5. 可选的盐值(Salt),其为一个随机数,是为了增加暴力破解的难度。

通过这些输入参数,KDF将输出指定长度的密钥(Key of required length)。

2.6 Diffie-Hellman安全性

Trapdoor function

陷门函数(Trapdoor function),是一种进行正向计算很容易,反向计算极其困难的函数。
Diffie-Hellman安全性
(如上图所示)现在,我们继续讨论Diffie-Hellman密钥交换问题。在Diffie-Hellman示例中,由于p、g、A、B都是众所周知的,这意味着黑客Harry也可以访问这些数字。我们可能会产生疑问:根据p、g、A、B和给定函数能否计算出a、bS这种密钥交换机制安全吗?
答案是安全的,因为这些用于计算的函数均是陷门函数。例如,如果我们为p、g、a、b选择好一个值,例如选择p作为2048位素数,选择g作为p的模,并选择a、b为256位随机整数,在这种情况下,给定p、g和a很容易计算出A,但是给定p、g和A,要计算出a很难。很容易看书,A可以用O(log(a)) 时间复杂度快速计算,这是一个模块化求幂问题。另一方面,计算a是一个离散对数问题,计算起来要困难得多,这需要我们当前的计算机花费很长的时间解决。所以我们目前的使用Diffie-Hellman至少是安全的,或者直到下一代强大的量子计算机出现后才会受到影响。

虽然Diffie-Hellman是一个需要很长时间解决的问题,但是并不意味着无法解决,是吗?
如果我们在会话过程中使用的都是固定的密钥S,又名静态密钥Static Key),将会产生潜在的危险,具体分析如下。

Static Key

static key
(如上图所示)如果Alice和Bob在他们交流的每个环节中,都使用固定的私钥ab,然后发生的是,Harry可以记录所有这些会话,然后从Session1开始解决a问题,尽管他要花很长时间才能解决,假设在SessionN之后,他得到了正确的a,然后他可以用a来计算出密钥S,从而他将能解密出所有记录的会话内容。

以上情况看起来很吓人!我们要如何预防呢?
答案是使用临时密钥Ephemeral Key)。

Ephemeral Key

Ephemeral Key
(如上图所示)顾名思义,我们在每个会话中使用不同的密钥(S1、S2…),即使Harry可以解决一次会话的密钥,他也不能将该密钥用于其他会话。这在TLS中称为完全前向保密Perfect Froward Secrecy)。

目前为止,我相信你已经完全了解了Deffie-Hellman Ephemeral DHE的含义,即使用临时密钥的Deffie-Hellman密钥建立协议。

三、非对称加密(Asymmetric cryptography)

非对称加密可用于以下三个方面:

  1. 密钥交换,例如上文示例中产生的密钥S
  2. 加密系统,使用的非对称加密算法例如:RSA-OAEP,RSA-PKCS1-v2.2
  3. 数字签名,这是非对称加密的一个重要特征。在TLS中广泛用于身份验证,TLS中常用的一些数字签名算法是:带有概率的RSA签名算法、Elliptic-Curve数字签名算法、Edwards-Curve数字签名算法,

在学习数字签名算法之前,先来学习下非对称加密系统是如何工作的?

3.1 工作原理

在非对称加密体系中:公钥和私钥是成对出现的,若是公钥加密,则私钥解密,若是私钥加密,则公钥解密,即互相解密,在私钥加密的情形中,又常称为私钥签名,公钥验证。即使用场景为:

  • 公钥加密,私钥解密。公钥对信息加密后只有对应的私钥可以解密。
  • 私钥签名,公钥验证。私钥对信息的签名,指的是私钥对信息加密后产生的密文,该密文只有对应的公钥可以解密,即公钥拥有者可以验证该密文是否是私钥拥有者发出的。

Asymmetric cryptography
(如上图所示)同对称加密一样,Alice想发送一条消息给Bob,但是这一次,没有共享密钥,而是使用非对称加密的公私钥,Alice使用Bob的公钥(Bob’s public key)对消息加密,并将加密的消息发送给Bob,当Bob收到消息时,它使用自己的私钥(Bob’s private key)对其进行解密,尽管公钥和私钥不同,但是它们仍然可以通过一些陷门函数关联在一起,就像我们在Diffie-Hellman算法中看到的一样。
在非对称加密的情况下,即使黑客Harry可以访问Alice的加密消息和Bob的公钥,他也不能使用Bob的公钥来解密消息。

3.2 如何分享公钥

由非对称加密原理可知,分享公钥变得极其简单,Bob可以直接通过互联网将密钥发送给Alice,无用担心公钥可用于解密任何消息。公钥分享的关键是完全公开的,因此,任何人都可以使用它来加密只有Bob可以阅读的消息,其分享流程如下图所示。
Public Key Sharing
你认为这个公钥分享方案真的安全吗?
若直接使用以上公钥分享方案,其现实情况并不那么简单。
在这里插入图片描述
(如上图所示)尽管我们知道Harry不能使用Bob的公钥解密邮件,但他仍然可以干扰公钥的分享,并用他自己的公钥替换Bob的公钥。现在,当Alice收到公钥时,她仍然认为这是Bob的公钥,但实际上是Harry的公钥。因此,如果Alice使用此公钥加密她的消息,Harry可以用他的私钥解密消息,然后再用Bob的公钥对解密后的消息加密,再发送给Bob,如此一来,Bob和Alice在通信过程中对Harry无感知。发生这种情况的原因是,因为公钥只是一串数字,而没有身份信息可以告诉我们其所有者是谁。

那么我们应该如何解决没有身份信息的问题呢?
显然,我们应该将密钥与一些身份消息放在一起,然后再共享出去,即所谓的数字证书。于是,Bob把他的公钥放在证书里,证书上有他的姓名和其他身份信息,该证书就像现实世界中的护照一样。

但是我们如何知道真正拥有证书的是Bob?是如何阻止了Harry用Bob的名字,但用Harry的公钥制作假证书?
结合护照的知识对证书的理解
(如上图所示)就像现实世界中一样,护照必须由护照颁发机构经过身份验证的过程后签发。在数字世界中,证书必须由证书颁发机构验证并签名,该证书颁发机构和护照颁发机构均是受信任的第三方

3.3 数字证书的获取

获取数字证书,即证书颁发机构对数字证书的颁发过程。
证书签名过程
(如上图所示)Bob已有一对公钥和私钥,现在他准备开始申请证书颁发机构对数字证书的签名:

  1. 创建证书签名请求CSR(Certificate Signing Request),该CSR包含他的公钥和一些身份信息,例如他的姓名、组织或电子邮件。
  2. 使用Bob的私钥对CSR进行签名(就像我们在护照上签名一样),然后将已签好名的CSR发送给证书颁发机构(Certificate Authority,简称CA)。
  3. CA用证书中Bob的公钥来验证他的签名,这是为了确保Bob确实拥有CSR中公钥所对应的私钥。如有必要,还需联系Bob验证其身份。
  4. CA使用自己的私钥在证书上签名(就像护照颁发机构在护照上盖一个钢印,然后将其发送回Bob。

现在,Bob与Alice可以共享此证书,证书中包含Bob的公钥和一些身份信息,而不是像以前那样仅发送公钥,Alice收到证书后,Alice可以使用证书颁发机构的公钥轻松验证证书的真实性。因此,Harry无法再用他的公钥替换Bob的公钥,因为他没有CA的私钥来签名假证书。数字证书的共享流程如下图所示:在这里插入图片描述
请注意,以上的安全的前提是我们都信任CA。如果以某种方式CA不可信,例如,如果CA给Harry他们的私钥,那么我们将面临严重的危险!解决CA可信问题的方法是,使用CA链

3.4 CA链

CA链是为了解决CA的可信任问题。
A chain of certificate authorities
(如上图所示)CA链的顶层是根证书颁发机构(Root Certificate Authority),它可以签署自身证书与签署中间CA(Intermediate Certificate Authority)证书。而该中间CA又可以签署其子节点CA证书,或者他们可以直接签署最终实体证书(即叶子证书)。如此,确保每个证书都引用了其上一节点的证书,可以追溯到根节点的证书,例如我们使用叶子节点的公钥解密(验证)叶子节点证书签名后,可以获得上一节点的签名,直至根节点。
在我们使用的操作系统和浏览器中存储了受信任的根证书颁发机构的证书列表,这样,操作系统和浏览器就可以轻松地验证所有证书的真实性。

3.5 数字证书的签名与验证

数字证书的签名与验证
(如上图所示)数字证书的签名与验证流程:
CA对证书的签名

  1. Hash:CA使用Hash算法计算出签署内容的一个Hash值,即d95e0dba36。
  2. Encrypt:CA使用其私钥对Hash值进行签名,签名值为1f96d4c362。
  3. Attach:签名附加到证书文件中,就完成了对证书的数字签名。

用户验证证书

  1. Detach:从已签名证书中解析出签名(1f96d4c362)与不带签名的证书
  2. Decrypt:使用CA的公钥对签名进行解密,获取到加密前的Hash值(d95e0dba36)。
  3. Hash:对不带签名的证书进行哈希运算,获取到Hash值,例如为:d95e0dba36。
  4. Compare:对比前后两个Hash值,如果它们相同,则签名有效。

至此,我们已经了解了对称加密与非对称加密,下面将探索如何在TLS 的握手协议中使用这两种加密方式。

四、TLS 1.3 握手流程

4.1 完整的握手流程

完整的握手流程
TLS 1.3 完整的握手流程主要包括以下三个步骤。

1、首先是客户端到服务器的Client Hello,消息内容包括:

  • 支持的协议版本:TLS 1.3 或 TLS 1.2。
  • 支持的对称密钥套件:TLS_AES_256_GCM_SHA384 或 TLS_CHACHA20_POLY1305_SHA256。
  • 支持的密钥协定(交换)算法:DHE(Diffie-Hellman Ephemeral) 或 ECDHE(Elliptic-Curve Diffie-Hellman Ephemeral)。
  • 分享的密钥:客户端的DHE公钥,客户端的ECDHE公钥,用于计算临时的共享密钥,即前文示例中的S。
  • 支持的签名算法:RSA-PSS 或 ECDSA,由服务器选择使用哪种算法对整个握手进行签名。

2、 收到客户端的Client Hello后,服务器将回复一个Server Hello,消息内容包括:

  • 选择的协议版本:TLS 1.3.
  • 选择的对称密钥套件:TLS_AES_256_GCM_SHA384。
  • 选择的密钥协定算法:DHE。
  • 分享的密钥:服务器的DHE公钥。
  • 证书请求:对客户端证书的请求,可选值,通常在HTTPS中,只需要服务器将其证书发送给客户端即可。。
  • 服务器证书:服务器的证书。
  • 证书验证:对整个握手消息的签名。生成方式:从客户端的握手开始,直到证书请求为止,都称为握手上下文(Handshake context),然后将握手的上下文以及服务器的证书经过Hash运算,得到一个hash值,例如4ab31d2,然后使用服务器的私钥对hash值进行签名,使用的签名算法为客户端支持的算法之一,最后获得填写的签名值。
  • 服务完成:为一个MAC值(消息认证码)。生成方式:对握手上上下文+服务器证书+证书验证进行Hash运算,再将hash值通过所选的密码套件计算出MAC值。

3、客户端收到Server Hello后,将通过根CA验证服务器证书,然后检查签名和MAC值,确保消息没有被篡改。若一切顺利,则客户端将发送一个握手结束消息,结束消息中包括:

  • 由握手上下文计算的MAC值、以及可选的客户端证书和证书验证。

以上便是TLS 1.3中的完整握手流程。

4.2 预共享密钥

预共享密钥(Pre-Shared Key),简称PSK。
PSK
(如上图所示)为了提高效率,客户端与服务器并不会每次都经过完整的握手流程,有时他们仅执行简短的握手流程,实现方法是通过预共享密钥恢复状态:经过前一次握手,客户端与服务器已经相互了解,因此他们不需要再次进行身份验证,因此,服务器可以向客户端发送一个或多个会话凭证(session ticket),可以在下一次握手中用预共享密钥(PSK)、凭证过期时间以及其他一些信息用作身份验证。
使用PSK的简短握手流程中,客户端将发送一条简单的问候消息,其中包括上一次握手获得的PSK身份标识(凭证)和PSK密钥交换模式,如果使用具有Diffie-Hellman模式的PSK,客户端还需要共享其Diffie-Hellman公钥。如有需要,允许服务器回退到完整的握手流程。服务器收到此客户端的问候消息时,它将返回带有选定的预共享密钥标识消息,服务器可在返回消息中带有可选的Diffie-Hellman公钥。最后,客户端发送给服务器一个完成消息。

可以看出,在该简短的握手流程中,客户端与服务器之间没有证书身份验证。这为零个往返时间(0-RTT)提供了机会。

4.3 0-RTT

0-RTT(Zero Round-Trip Time)意味着,客户端无需等待握手完成,就可将第一个应用请求数据发送给服务器。
0-RTT
(如上图所示)在0-RTT中,客户端将应用程序数据(Application data)和客户端Client Hello消息一起发送,客户端使用Pre-shared key字段中的第一个PSK派生的密钥对数据进行加密,同时,该Client Hello增加了早期数据指示(Early data indication)字段,告诉服务器有早期的应用数据正在发送。如果服务器接收此0-RTT请求,它会像正常的PSK恢复一样发送一个回复消息,可能回复消息中带有一些可选的应用程序数据。最后,客户端发送一个带有早期数据的结束与MAC值得结束消息。

以上就是TLS 1.3中0-RTT的工作方式。它的优点时将延迟减少了 1 个往返时间,但是,其缺点是将会收到重放攻击的潜在威胁,意思是,黑客可以复制并发送相同加密的0-RTT请求多次访问服务器,为了避免这种情况,必须实现服务器应用程序对重复请求的方式限制,例如1s之内只能访问5次。

五、时序图(2022/8/11补充)

在这里插入图片描述
整理文件的过程中,找到了早先实现的代码,逻辑与上图所示一致,实现语言为Go,可前往资源中心下载。

希望你也有所收获!

参考文献:A complete overview of SSL/TLS and its cryptographic system

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_30145355/article/details/112984487

智能推荐

手机邮箱注册技术分析及运用-网站如何发送验证码到手机注册账号_手机号登录邮箱咋发验证码-程序员宅基地

文章浏览阅读2.1k次。手机邮箱注册技术分析及运用-如何用邮箱注册账号,请参考以下文章: https://blog.csdn.net/weixin_42828741/article/details/82625077本文主要讲述如何使用手机注册账号~目前了解到的服务商有以下几种: 阿里云短信 -腾讯云短信 -百度云SMS -容联云通讯(本文介绍的是这种)接入步骤(以容联云通讯为例测试) 1.注册开发..._手机号登录邮箱咋发验证码

开发钉钉和企业微信微应用_做个app用于钉钉和企业微信用什么编程软件-程序员宅基地

文章浏览阅读1.1k次。1、登录企业微信管理后台 -- 创建企业内部应用 -- 填写logo和应用名称--配置域名 (与钉钉类似)这样ios在点击输入框的时候就不会出现页面被顶起来导致页面变形的问题了。3、配置首页可访问地址:打包到线上的路径(注意配置正式环境和本地环境)2、安装对应的插件和依赖。axios、router、scss等。2、上传内部应用logo和名字。注意需要添加可访问域名的配置。开发上线后会遇到很多有关安卓和ios的兼容性问题。4、在所在公司的工作台搜索应用名称即可。如果不添加配置会自动跳转到线上的地址。_做个app用于钉钉和企业微信用什么编程软件

CentOS 部署easy-mock注意事项_easymock部署在centos7中 不能访问-程序员宅基地

文章浏览阅读255次。https://github.com/easy-mock/easy-mock常用linux命令查看端口占用情况netstat -lnpt |grep 80netstat -an|grep 7301系统管理角色,里面切换rootsudo su -查找一个叫 app 的进程ps -ef|grep app杀掉进程kill -9 pid1、安装nodejs 一定要安装8..._easymock部署在centos7中 不能访问

RILD - 第二章 - EventLoop机制的建立_rild_event-程序员宅基地

文章浏览阅读734次。二、EventLoop机制LibRIL负责接收来自RILJ的数据,并传递给ReferenceRIL。实现这一功能的主要机制就是EventLoop机制。 分析LibRIL主要就是分析EventLoop。2.1 EventLoop相关预备知识2.1.1 EventLoop中的Event在ril_event.h头文件中可以看到ril_event的结构体定义//定义Event回调函数指针typedef_rild_event

[JS 工具] 格式化显示 mailman 上的 diff 文本-程序员宅基地

文章浏览阅读122次。公司使用 mailman 来显示 patch,mailman 显示的改动只有一堆黑白文字,难以辨认。有时候还把 patch 当成文件再 git add 一遍后再生成一个新的 patch,这时候对于原来 patch 的代码改动来说,整个 patch 都是新增代码,就更加难以看出改动在哪,给 review patch 带来不必要的不便。有天我想可不可以做成跟 github 一样,至少增删有不..._diff2htmlui

Qt 之 信号参数为QSharedPointer 智能指针类型_qsharedpointer 引用自定义类型-程序员宅基地

文章浏览阅读3k次,点赞2次,收藏15次。文章目录智能指针作为信号参数QSharedPointer智能指针作为信号参数/*! connect a module to the event bus*/Q_DECLARE_METATYPE( QSharedPointer<GitlEvent> )bool GitlEventBus::registerModule(GitlModuleDelegate* pcModule){ qRegisterMetaType< QSharedPointer<GitlEve_qsharedpointer 引用自定义类型

随便推点

linux中chdir函数,linux之chdir函数解析-程序员宅基地

文章浏览阅读891次。[lingyun@localhost chdir]$ lschdir.c[lingyun@localhost chdir]$ cat chdir.c/********************************************************************************** Copyright: (C) 2013 fulinux* ..._linux chdir 函数

python批量录入学生信息_基于Python的学生信息管理系统-程序员宅基地

文章浏览阅读1.5k次。开发环境要求本系统的软件开发及运行环境具体如下。操作系统:Windows 7、Windows 10。Python版本:Python 3.7.0。开发工具:Python IDLE。运行方法在项目文件studentsystem.py上单击鼠标右键,在弹出快捷菜单中选择“Edit with IDLE\Edit with IDLE 3.7(64-bit)”菜单项,如图1所示。在打开的Python Shel..._python从键盘输入 n 个学生信息,包括学号、姓名、成绩。保存到 e:\students.txt

基于SpringBoot+Vue工厂生产设备维护管理系统设计和实现(源码+LW+部署讲解)-程序员宅基地

文章浏览阅读826次,点赞12次,收藏22次。随着社会的发展,系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但各种信息鱼龙混杂,信息真假难以辨别。为了方便用户更好的获得工厂生产设备维护信息,因此,设计一种安全高效的工厂生产设备维护管理系统极为重要。为设计一个安全便捷,并且使用户更好获取工厂生产设备维护信息,本文主要有安全、简洁为理念,实现用户快捷寻找工厂生产设备维护信息,从而解决工厂生产设备维护信息复杂难辨的问题。该系统采用java语言、Spring Boot框架和mysql数据库进行开发设计,通过对。

mysql基准测试-程序员宅基地

文章浏览阅读708次。mysql 基准测试_mysql基准测试

两个八进制小数怎么相加_八进制怎么算-程序员宅基地

文章浏览阅读1.4k次。展开全部1、八进制化为32313133353236313431303231363533e78988e69d8331333366306436十进制:例:将八进制数12转换成十进制数 2、八进制化为二进制:规则:按照顺序,每1位八进制数改写成等值的3位二进制数,次序不变。例: (17.36)8 = (001 111 .011 110)2 = (1111.01111)23、八进制化为十六进制先..._两个八进制相加

【十年开发积累】STM32产品开发代码案例合集,嵌入式物联网工程师珍贵资料(物联技术666)_基于stm32f103单片机的经典应用实例源码合集(76例)-程序员宅基地

文章浏览阅读1k次,点赞30次,收藏15次。例程涵盖:STM32各类功能配置,外围传感器初始化,模块初始化,物联网协议,操作系统移植,功能开发,产品案例等等,十分具有参考价值。_基于stm32f103单片机的经典应用实例源码合集(76例)

推荐文章

热门文章

相关标签