范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

货拉拉SSL证书踩坑之旅

  一、背景简介1、遇到的问题
  2020年,货拉拉运营部门和客户端开发对齐了https网络通信协议中的SSL网络证书校验方案;但是由于Android客户端的证书配置不规范,导致在客户端内置的SSL网络证书到期前十几天被发现证书校验异常,Android客户端面临全网访问异常的问题 2、本文内容
  本文主要介绍解决货拉拉Android客户端SSL证书到期的解决方案及Android端SSL证书相关知识 二、SSL证书简介1、SSL证书诞生背景
  1994年,Netscape公司首先使用了SSL协议,SSL协议全称为:安全套接层协议(Secure Sockets Layer),它指定了在应用程序协议(如HTTP、Telnet、FTP)和TCP/IP之间提供数据安全性分层的机制,它是在传输通信协议(TCP/IP)上实现的一种安全协议,采用公开密钥技术,它为TCP/IP连接提供数据加密、服务器认证、消息完整性以及可选的客户端认证。由于SSL协议很好地解决了互联网明文传输的不安全问题,很快得到了业界的支持,并已经成为国际标准
  HyperText Transfer Protocol over Secure Socket Layer。在HTTPS中,使用传输层安全性(TLS)或安全套接字层(SSL)对通信协议进行加密。也就是HTTP+SSL(TLS)=HTTPS
  2、SSL证书简介
  按类型划分,SSL证书包括CA证书、用户证书两种 (1)CA证书(Certification Authority证书颁发机构)
  证书的签发机构(CA)颁发的电子证书,包含根证书和中间证书两种
  [i]根证书
  属于根证书颁发机构(CA)的公钥证书,是在公开密钥基础建设中,信任链的起点
  一般客户端会内置
  [ii]中间证书
  因为根证书太宝贵了,直接颁发风险太大了。因此,为了保护根证书,CAs通常会颁发所谓的中间证书。CA使用它的私钥对中间证书签名,使它受到信任。然后CA使用中间证书的私钥签署和颁发终端用户SSL证书。这个过程可以执行多次,其中一个中间根对另一个中间根进行签名 (2)用户证书
  用户证书是由CA中间证书签发给用户的证书,包含服务器证书、客户端证书
  [i]服务器证书
  组成Web服务器的SSL安全功能的唯一的数字标识。 通过CA签发,并为用户提供验证您Web站点身份的手段。
  服务器证书包含详细的身份验证信息,如服务器内容附属的组织、颁发证书的组织以及称为公开密钥的唯一的身份验证文件
  [ii]客户端证书
  在双向https验证中,就必须有客户端证书,生成方式同服务器证书一样;
  单向证书则不用生成 3、SSL证书链
  SSL证书链是从用户证书、生成用户证书的CA中间证书、生成CA中间证书的CA中间证书...一直到CA根证书;其中根证书只能有一个,但是CA中间证书可以有多个
  (1)以baidu的证书为例
  (2)证书链
  客户端(比如浏览器或者Android手机)验证我们SSL证书的有效性的时候,会一层层的去寻找颁发者的证书,直到自签名的根证书,然后通过相应的公钥再反过来验证下一级的数字签名的正确性
  任何数字证书都必须要有根证书做支持,有了根证书的支持才说明这个数字证书是有效的是被信任的
  4、SSL证书文件的后缀
  证书的后缀主要有.key、.csr、.crt、.pem等
  (1).key文件:密钥文件,SSL证书的私钥就包含在其中
  (2).csr文件:这个文件里面包含着证书的公钥和其他一些公司信息,通过请求签名之后就可以直接生出证书
  (3).crt文件:该文件中也包含了证书的公钥、签名信息以及根据不同类型证书携带不同的认证信息,如IP等(该文件在有些机构、系统中也可能表现为.cert后缀)
  (4).pem文件:该文件相对比较少见,里面包含着证书的私钥以及部分证书信息 5、SSL用户证书类型
  SSL用户证书主要分为(1)DV SSL证书 (2)OV SSL证书 (3)EV SSL证书
  (1)DV SSL证书(域名验证型):只需验证域名所有权,无需人工验证申请单位真实身份,几分钟就可颁发的SSL证书。价格一般在百元至千元左右,适用于个人或者小型网站
  (2)OV SSL证书(企业验证型):需要验证域名所有权以及企业身份信息,证明申请单位是一个合法存在的真实实体,一般在1~5个工作日颁发。价格一般在百元至几千元左右,适用于企业型用户申请
  (3)EV SSL证书(扩展验证型):除了需要验证域名所有权以及企业身份信息之外,还需要提交一下扩展型验证,通常CA机构还会进行电话回访,一般在2~7个工作日颁发证书。价格一般在千元至万元左右,适用于在线交易网站、企业型网站 6、SSL证书结构
  7、SSL证书查看
  以Chorme上的baidu为例:
  第1步
  第2步
  第3步
  三、客户端SSL证书校验流程1、客户端SSL证书校验主要是在网络连接的SSL/TLS握手环节校验
  SSL/TLS握手(用非对称加密的手段传递密钥,然后用密钥进行对称加密传递数据)
  校验流程主要在上述过程的第三步和第六步
  第三步:Certificate
  Server——>Client 服务端下发公钥证书
  第六步:证书合法性校验
  Client 对 Server下发的公钥证书进行合法性校验 2、客户端证书校验过程
  (1)校验证书是否是受信任的CA根证书颁发机构颁发
  客户端通过服务器证书 中签发机构信息,获取到中间证书公钥;利用中间证书公钥进行服务器证书的签名验证
  a、中间证书公钥解密 服务器签名,得到证书摘要信息;
  b、摘要算法计算 服务器证书 摘要信息;
  c、然后对比两个摘要信息。
  客户端通过中间证书中签发机构信息,客户端本地查找到根证书公钥;利用根证书公钥进行中间证书的签名验证 (2)客户端校验服务端证书公钥及摘要信息
  客户端获取到服务端的公钥:Https请求 TLS握手过程中,服务器公钥会下发到请求的客户端。
  客户端用存储在本地的CA机构的公钥,对服务端公钥中对应的摘要信息进行解密,获取到服务端公钥的摘要信息A;
  客户端根据对服务端公钥进行摘要计算,得到摘要信息B;
  对比摘要信息A与B,相同则证书验证通过 (3)校验证书是否在上级证书的吊销列表
  若证书的申请主体出现:私钥丢失、申请证书无效等情况,CA机构需要废弃该证书
  (详细策略见《四、Android端证书吊销校验策略》) (4)校验证书是否过期
  校验证书的有效期是否已经过期:主要判断证书中** Validity period  **字段是否过期(ps:Android系统默认不校验证书有效期,但浏览器和ios系统默认会校验证书有效期)(5)校验证书域名是否一致
  校验证书域名是否一致: 核查   证书域名  是否与当前的访问域名   匹配  。
  比如:我们请求的域名 www.huolala.cn 是否与** 证书文件  中DNS标签  下所列的域名  相匹配  **;
  四、Android端证书吊销校验策略1、证书吊销校验主要存在两类机制:CRL 与 OCSP(1)证书吊销列表校验:CRL(Certificate Revocation List)
  证书吊销列表:是一个单独的文件,该文件包含了 CA机构 已经吊销的证书序列号与吊销日期;
  证书中一般会包含一个 URL 地址 CRL Distribution Point,通知使用者去哪里下载对应的 CRL 以校验证书是否吊销。
  该吊销方式的优点是不需要频繁更新,但是不能及时吊销证书,这期间可能已经造成了极大损失 (2)证书状态在线查询:OCSP(Online Certificate Status Protocol)
  证书状态在线查询协议:一个实时查询证书是否吊销的方式。
  请求者发送证书的信息并请求查询,服务器返回正常、吊销或未知中的任何一个状态。
  证书中一般也会包含一个 OCSP 的 URL 地址,要求查询服务器具有良好的性能。
  部分 CA 或大部分的自签 CA (根证书)都是未提供 CRL 或 OCSP 地址的,对于吊销证书会是一件非常麻烦的事情 2、Android系统默认使用CRL方式来校验证书是否被吊销
  核心实现类是CertBlocklistImpl(维护了本地黑名单列表),部分源码逻辑如下: (1)TrustManagerImpl(证书校验核心类)
  第1步循环校验信任证书
  第2步检查该证书是否在黑名单列表里面
  (2)CertBlocklistImpl(证书黑名单列表维护类)
  黑名单校验逻辑:主要检查是否在黑名单列表里面
  黑名单本地存储位置
  可以看到黑名单文件储存在环境变量"ANDROID_DATA"/misc/keychain/pubkey_blacklist.txt;
  可以通过adb shell--export--echo $ANDROID_DATA,拿到环境变量位置,一般在/data目录下 3、Android端自定义证书吊销校验逻辑
  核心类在TrustManagerFactory、CertPathTrustManagerParameters、PKIXRevocationChecker (1)TrustManagerFactory工厂模式的证书管理类
  有两种init方式
  [i]init(KeyStore ks) 默认使用
  传递私钥,一般传递系统默认或者传空
  以okhttp为例(默认传空)
  [ii]init(ManagerFactoryParameters spec) 自定义方式
  下面介绍下通过自定义方式来实现OCSP方式校验证书是否吊销 4、基于PKIXRevocationChecker方式自定义OCSP方式(1)自定义TrustManagerFactory.init(ManagerFactoryParameters spec)
  init方法传入基于CertPath的 TrustManager  CertPathTrustManagerParameters,包装策略PKIXRevocationChecker
  (2)PKIXRevocationChecker(用于检查PKIX算法的证书撤销状态)
  默认使用 OCSP方式校验,可以自定义使用OCSP策略还是CLR策略
  参考谷歌开发者文档:developers.google.cn/j2objc/java…
  五、Android端证书校验方式
  主要有四种校验方式:
  客户端单向认证服务端---证书锁定
  客户端单向认证服务端---公钥锁定
  客户端服务端双向认证
  客户端信任所有证书 1、客户端单向认证服务端---证书锁定(1)校验过程
  校验服务端证书的subject信息和publickey信息是否与客户端内置证书一致,如果不一致会报错:
  "java.security.cert.CertPathValidatorException: Trust anchor for certification path not found" (2)实现方式
  [i] network-security-config配置方式
  (生效范围:app全局,包含webview请求)
  (只支持android7.0及以上)
  [ii]代码配置方式(生效范围:配置了该SSLParams的实例)
  (3)优点
  校验了subject信息和publickey信息,防信息篡改的安全等级高一点 (4)缺点
  [i]因为一般网络证书的有效期是1-2年,所以面临过期之后可能校验异常的问题(ps:本次货拉拉客户端遇到的就是这种内置的网络证书快到期的case)
  [ii]内置在app里面,证书容易泄漏 2、客户端单向认证服务端---公钥锁定(1)校验过程
  校验服务端证书的公钥信息是否与客户端内置证书的一致 (2)实现方式
  [i] network-security-config配置方式
  (生效范围:app全局,包含webview请求)
  (只支持android7.0及以上)
  [ii]代码配置方式(生效范围:配置了该参数的实例)
  (3)优点
  只要服务端的公钥保持不变,更换证书也能通过校验 (4)缺点
  只校验了公钥,防信息篡改的安全等级低一点 3、客户端和服务端双向认证(1)实现方式
  自定义的SSLSocketFactory实现客户端和服务端双向认证 public class SSLHelper {      /** * 存储客户端自己的密钥 */  private final static String CLIENT_PRI_KEY = "client.bks";       /** * 存储服务器的公钥 */  private final static String TRUSTSTORE_PUB_KEY = "publickey.bks";      /** * 读取密码 */  private final static String CLIENT_BKS_PASSWORD = "123321";      /** * 读取密码 */  private final static String PUCBLICKEY_BKS_PASSWORD = "123321";      private final static String KEYSTORE_TYPE = "BKS";      private final static String PROTOCOL_TYPE = "TLS";      private final static String CERTIFICATE_STANDARD = "X509";      public static SSLSocketFactory getSSLCertifcation(Context context) {          SSLSocketFactory sslSocketFactory = null;          try {             // 服务器端需要验证的客户端证书,其实就是客户端的keystore             KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);             // 客户端信任的服务器端证书             KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);              //读取证书             InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);             InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);              //加载证书             keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());             trustStore.load(tsIn, PUCBLICKEY_BKS_PASSWORD.toCharArray());              //关闭流             ksIn.close();             tsIn.close();              //初始化SSLContext             SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);             TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);             KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);              trustManagerFactory.init(trustStore);             keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());              sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);             sslSocketFactory = sslContext.getSocketFactory();         } catch (KeyStoreException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         } catch (CertificateException e) {             e.printStackTrace();         } catch (NoSuchAlgorithmException e) {             e.printStackTrace();         } catch (UnrecoverableKeyException e) {             e.printStackTrace();         } catch (KeyManagementException e) {             e.printStackTrace();         }         return sslSocketFactory;     }  } 复制代码(2)优点
  双向校验更安全(3)缺点
  需要服务端支持,TLS/SSL握手耗时增长4、客户端信任所有证书
  不检验任何证书,下面列两种常见的实现方式(1)OkHttp版本
  (2)HttpURLConnection版本
  六、Android端一种源码调试的方式
  背景:由于证书校验相关源码不在Android.jar中,为了方便调试证书校验的流程,这里简单介绍一种非android.jar包中的Android源码调试的方式1、下载源码(1)源码地址:android.googlesource.com/
  android官方提供了各个模块的git仓库地址
  (2)以SSL证书调试为例
  我们只需要conscrypt部分的源码:android.googlesource.com/platform/ex…
  注意点:选择的分支要和被调试的手机版本一致(因为不同系统版本下源码有点区别)
  如果测试及时Android10.0系统,我们可以选择android10-release分支
  2、源码导入
  新建一个module 把刚才的系统源码复制进来,不需要依赖,只需要在setting.gradle中include,这样做隔离性好,方便移除
  3、源码编译
  导入源码之后,可能会有部分编译问题,可以解决的可以先解决,如果解决不了可以先注释;
  需要注意点:
  (1)不能修改行号,否则调试的时候走不到
  (2)不能新增代码,新增的代码不会执行4、断点调试
  打好断点就可以发车了
  可以看到app发起网络请求之后会走到TrustManagerImpl里面的checkServerTrusted校验服务端证书
  七、Android端证书校验源码解析1、证书校验主要分3步(1)握手过程中验证证书
  验证证书合法性,判断是否由合法的CA签发,由上面的Android系统根证书库来判断
  (2)验证域名
  判断服务端证书是否为特定域名签发,验证网站身份,这里如果出错就会抛出
  SSLPeerUnverifiedException  的异常
  (3)验证证书绑定
  2、Android根证书相关源码
  Android会内置常用的根证书,系统根证书存放在/system/etc/security/cacerts 目录下,文件均为 PEM 格式的 X509 证书格式,包含明文base64编码公钥,证书信息,哈希等
  Android系统的根证书管理类
  位于/frameworks/base/core/java/android/security/net/config   目录下
  以下是根证书管理类的类关系图
  (1)CertificateSource
  接口类,定义了对根证书可执行的获取和查询操作
  有三个实现类,分别是KeyStoreCertificateSource、ResourceCertificateSource、DirectoryCertificateSource(2)KeyStoreCertificateSource
  从 KeyStore 中获取证书
  (3)ResourceCertificateSource
  基于 ResourceId 从资源目录读取文件并构造证书
  (4)DirectoryCertificateSource(抽象类)
  遍历指定的目录 mDir 读取证书;还提供了一个抽象方法 isCertMarkedAsRemoved()   用于判断证书是否被移除
  SystemCertificateSource   和 UserCertificateSource   继承了DirectoryCertificateSource并且分别定义了系统和用户根证书库的路径,并实现抽象方法
  [i]SystemCertificateSource
  定义了系统证书查询路径,并且还指定了被移除的证书文件的目录
  判断证书是否移除就是直接判断证书文件是否存在于指定的目录
  [ii]UserCertificateSource
  定义了用户证书指定查询路径,证书是否移除永远为false
  3、Android证书校验源码
  (以证书锁定方式的单向校验服务端证书为例)
  核心类TrustManagerImpl、TrustedCertificateIndex、X500Principal
  (1)第一步checkServerTrusted()
  (2)第二步checkTrusted()
  (3)第三步TrustedCertificateIndex类匹配证书issuer和signature信息
  private final Map subjectToTrustAnchors
  = new HashMap();
  可以看到获取TrustAnchor是通过HashMap的key X500Principal匹配获取的,
  (4)X500Principal
  private transient X500Name thisX500Name;
  查看X500Principal的源码可以看到它覆写了equals()方法,对比的是属性中的thisX500Name
  调试下来发现我们客户端证书的 thisX500Name 的值为
  "CN=*. huolala.cn , OU=IT, O=深圳货拉拉科技有限公司, L=深圳市, ST=广东省, C=CN"
  (ps:后面会提到,货拉拉客户端证书异常主要因为新证书缺少了OU字段)
  (5)subject和issue信息
  八、货拉拉SSL证书踩坑流程1、背景简介
  2020年7月份的时候,货拉拉出现了因为网络证书过期导致的异常,所以运维的同事拉了客户端的同事一起对齐了方案,使用上述《客户端单向认证服务端---公钥锁定》的方式
  由于历史原因:
  货拉拉用户端使用了上述(三、1(2)客户端单向认证服务端---证书锁定,代码配置方式)
  货拉拉司机端使用了上述(三、1(1)客户端单向认证服务端---证书锁定,network-security-config配置方式)
  2021年7月份的时候,运维同事更新了服务端的证书,因为更换过程中没有出现异常,所以运维的同事以为android端都是按照之前约定的《客户端单向认证服务端---公钥锁定》方式
  (但实际原因是用户和司机端提前内置了2022-8-19过期的证书)2、线上出现异常
  2022-8-1的时候,运维同事开始操作更新服务端2023年的证书,在更新了H5部分域名的证书之后,司机Android端出现部分网页白屏的问题
  排查之后发现服务端更新了证书导致客户端证书校验证书非法导致异常
  2022-8-2的时候开始排查用户端的逻辑,发现是《客户端单向认证服务端---证书锁定,代码配置方式》,测试之后发现
  (1)删除app内置2022年的证书,只保留2020年的证书之后,native请求异常,无法进入app
  (2)手动调整手机设备时间,发现native请求正常,webview白屏和图片加载失败
  意味着在服务端更换的证书2022-8-19到期之后,客户端将面临全网访问异常的问题3、第一次尝试解决
  测试的时候发现,android端在证书过期时仍然可以访问服务端(客户端和服务端都保持一致的2022年的证书);
  所以想的第1个解决方案是服务端仍然使用2022-8-19的证书,直到大部分用户升级上来之后再更换新证书;
  但是ios和web发现如果服务端使用过期证书的情况,系统底层会拦截这个过期证书直接报错;
  所以无法兼容所有客户端4、第二次尝试解决
  在查看源码TrustManagerImpl类源码的时候发现,TrustManagerImpl的服务端检验只是校验了publickey(公钥),所以如果2022年的旧证书和2023年的新证书如果公钥一致的话,可能可以校验通过;
  所以想的第2个解决方案是服务端使用的新证书保持和2022-8-19的证书的公钥一致就可以;
  但是测试的时候发现native请求还是会报错
  "java.security.cert.CertPathValidatorException: Trust anchor for certification path not found"5、第三次尝试解决
  开发发现按照证书链的校验过程,如下:
  如果有中间证书,那么这个中间证书机构颁发的任何服务器证书都可以都校验通过;
  所以想出的第3个解决方案是服务器证书内置中间证书组成证书链;
  但是排查之后发现服务器证书和客户端内置的证书里面都已经包含了中间证书,所以依然行不通
  (ps:如果客户端内置的证书里面删除用户证书信息,只保留中间证书信息,那么只要是这家中间证书颁发的所有的服务器证书都是可以校验通过的,而且一般中间证书的有效期是10年,这也可以作为一个备选项,不过缺点是不安全)6、第四次尝试解决
  (1)测试同学在网上找到一篇《那些年踩过HTTPS的坑(二)——APP证书链mp.weixin.qq.com/s/yv_XcMLvr…
  所以想到的解决方案是重新申请一个带OU字段的新服务器证书
  (2)但是运维同事咨询了两家之前的中间商之后对方的回复都是新的证书已经不再提供OU字段,理由是
  (3)最后历经一言难尽的各种插曲最后找UniTrust颁发了带OU字段的新证书
  (ps:还在使用证书锁定方式校验的可以留意下证书里面的OU字段,后续证书都不会再提供)九、Android端证书校验的解决方案1、认证方式
  按照安全等级划分,从高到低依次为:
  (1)客户端和服务端双向认证,参考上述《五、Android端证书校验方式-3、客户端和服务端双向认证》
  (2)客户端单向认证服务端---证书锁定,参考上述《五、Android端证书校验方式-1、客户端单向认证服务端---证书锁定》
  (3)客户端单向认证服务端---公钥锁定,参考上述《五、Android端证书校验方式-2、客户端单向认证服务端---公钥锁定》
  可以根据各自的安全需求选择合适的认证方式2、校验方式(1)证书校验
  具体方式参考《五、Android端证书校验方式-1、客户端单向认证服务端---证书锁定》;
  为了增强安全性,app可以内置加密后的证书,将解密信息存放在加固后的c++端,增强安全性(2)公钥校验
  具体方式参考《五、Android端证书校验方式-2、客户端单向认证服务端---公钥锁定》;
  为了增强安全性,app可以内置加密后的公钥,将解密信息存放在加固后的c++端,增强安全性3、配置降级
  为了在出现异常情况时不影响app访问,可以添加动态配置和动态降级能力(1)动态配置
  动态下发公钥和证书信息,需要留意下发的时机要尽量早一点,避免证书异常时走不到下发的请求(2)动态降级
  动态降级证书校验功能,在客户端证书或者服务端证书出现异常时,支持动态关闭所有的证书校验的功能十、总结
  最后,总结一下整体的思路:
  1、SSL证书分为CA证书和用户证书
  2、客户端SSL证书校验是在网络连接的SSL/TLS握手环节进行校验
  3、SSL证书的认证方式分为(1)单向认证(2)双向认证
  4、SSL证书的校验方式分为(1)证书校验(2)公钥校验
  5、SSL证书的校验流程主要是校验证书是否是由受信任的CA机构签发的合法证书
  6、SSL证书的吊销校验策略分为(1)CRL本地校验证书吊销列表(2)OCSP证书状态在线查询
  7、纵观本次踩坑之旅,也暴露出一个比较深刻的问题:大部分的客户端开发的认知还是停留在app上层,缺少对底层技术的认识和探索,导致一个很小的配置问题差点酿成大的事故;这也为想在客户端领域进一步提升提供了一个思路:多学习客户端的底层技术,包含网络底层实现、安全、系统底层源码等等
  8、最后,解决技术类问题最核心的点还是学习和熟悉源代码;解决证书配置问题的过程中,走了不少弯路,本质上是最开始没有彻底掌握证书校验相关的系统源代码的逻辑,客观上是由于缺少非android.jar源码的调试手段导致阅读源码遗漏了部分校验逻辑,所以本次特意补上(六、Android端一种源码调试的方式),希望后续遇到系统级的疑难杂症可以用的上
  参考:
  https://www.cnblogs.com/xiaxveliang/p/13183175.html
  https://blog.csdn.net/weixin_35016347/article/details/105802480
  作者:货拉拉技术
  出处:https://juejin.cn/post/7186837003026038843

心理暗示有多大作用?妇专委特邀心理问答专家志愿者张海静,头条号心理健康专家海静。人这一生,从生到死,就是一场彻头彻尾的大暗示,无论是信奉宗教,还是信奉科学,每个人都一定有自己主观世界的原则,而这原则,几个朋友轮流请客,其中一个总是请大家去家里吃,是想省钱吗?几个朋友轮流请客,轮到其中一个时,老是请大家去家里吃,是想省钱吗?我非常想知道,你们几个朋友能轮流请客,说明你们友谊深厚。如果是真朋友,在外在家请客都一样享受这份情这份爱。从实际情为什么医护人员没有节假日,上班也没有三倍工资?医疗行业是需要724小时上班的,这就需要许多人上夜班节假日上班。特殊行业休假制度是有劳动法明确规定的,一般上一个夜班要休息一天,节假日上班要补休,这符合劳动法规定。医疗行业就是这样事实终将打败谎言,美联储无奈承认持续高通胀,会不会提前加息?谢邀!在回复美国经济矛盾,美联储竟无计可施,会不会引爆下一轮经济危机?(httpswukong。toutiao。comanswer7040118206169694501)中提到,大飞机进入平流层后平稳飞行,那么飞行员是否能够做别的事情?以民航飞机为例,由于航电系统的进步,通常采用双人制机组编制,即一名机长正驾驶位于左驾驶位,一名副驾驶位于右驾驶位。两人相互配合就可以完成对客机的全部驾驶操作,从起飞前准备滑跑起飞爬发量少头发细软的女生适合什么样的发型?关注糖小姐的闺蜜圈闺蜜美,世界才美不!你会比闺蜜更美!文末有惊喜!谢邀!发量少让很多人苦恼,特别是女生的话更加没得说了,本来发量就少了偏偏还是细软型的发质,更显得比别人还要单薄了许我是刚刚创业的年轻人,正在做肠粉,请问前辈们怎么解决肠粉腻口,吃起来感觉像肥猪肉的问题?造成以上提出的问题有几个原因。1米浆加太多油或刷盘油太多或淋酱油时加太多油,又或者不是纯正花生油而是不卫生的散装油,品质好的油用两只手指搓捏不会有粘粘的感觉很容易清洗油渍,品质差的18年的华为p20感觉有点卡了,要不要换?感谢您的阅读!华为P20这款手机的表现还是可圈可点的。这款手机虽然是老款手机,但是它的影像能力在当时确实是能够称得上表现突出的机型。你可以看到这款手机的具体的一些参数1。这款手机采为什么感觉老外讲英语不考虑语法?你好,谢谢邀请回答问题。我是今日头条英语万能王老师,给你一些对于问题为什么外国人讲英语不考虑语法的分析建议供你参考。1。大多数外国人出生就是从简单单词开始学习的,都是听爸爸妈妈教育北海有什么好玩的?素有中国最大城市氧吧之称的广西北海市,是古代海上丝绸之路的始发港,境内风光旖旎,文化底蕴深厚,如果您打算来北海旅游,以下景点最值得推荐北海银滩素有天下第一滩美誉的北海银滩,因沙质细联想到底有没有侵吞国有资产?不谈其他只讲中一点,柳传志贪占了倪光南院士无偿赠送给国家的汉卡及技术,而后柳传志又把倪院士扫地出门独占了,让一个原属100国有公司转换成柳传志为主的控股公司。再利用倪光南院士赠送给
最美京郊铁路怀密线最美京郊铁路怀密线北京的秋天是最美的,这已是公认的事实。所以每当秋天的时候,就是生活在北京的人们饱览北京大美景色的最佳时机。北京是一座古老与现代并举的国际化大都市,悠久的历史文化,遇见运河推介通州露营地原标题遇见运河推介通州露营地26日,通州区文旅融合新品牌遇见运河首场主题活动幸运一夏城市露营大会在大运河文化旅游景区南区开启。通州多个网红露营地借此机会集中向市民推介。露营是今年发1000公里自驾不用加油哈弗神兽柠檬超级混动表示压力不大如果你问一个内陆城市的上班族,开车兜风的时候配什么景色最合你的心意,可能有相当一部分的人会选择在滨海大道上吹着海风欣赏碧波荡漾。而有着关外第一市之称的葫芦岛就有着风景宜人的沿海公路纽卡斯尔签皇家社会前锋伊萨克,欧冠小组赛抽签仪式将进行2022年8月25日星期四北京时间8月25日0330,巴塞罗那坐镇主场与曼城进行一场慈善友谊赛。本场慈善赛是为了致敬患上渐冻症的巴萨前助理教练温苏埃,比赛收益也将用于对抗渐冻症。上泰国旅行1000人民币,能生活多久?服务有点惊讶众所周知,泰国不仅距我国较近,而且当地还有着性感的人妖表演。随着泰国旅游业的不断发展,当地也就成为了我国多数游客们出国旅游的必选地了。(此处已添加小程序,请到今日头条客户端查看)那自旋锁的底层实现简介自旋锁锁的作用就是保护临界区资源,避免不同的CPU同时访问相同的变量(或中断与进程同时访问相同变量)。非原子变量的赋值,大多数都不是一个指令周期能完成的,试想如果CPU1将某变手握70万,2022年应该存银行还是买房?3个现象告诉你真实答案要说现在中国的家庭资产中什么最重要,恐怕99的人都会说房产。是啊,房子不知不觉的成为一个家庭的主要资产,这个高房价分不开。可能还有人不相信这个结论,下面给大家看几组数据央行课题研究H阿隆索克洛普上任时我就知道他是正确人选蒂亚戈像巴西球员直播吧9月13日讯在下周利物浦传奇队对阵曼联传奇队的友谊赛之时,红军名宿哈维阿隆索将回到安菲尔德球场征战。在接受俱乐部官网的采访时,他谈到了自己与利物浦之间的联系。成为一名教练后,韩伯平回忆毛主席遗体栩栩如生的真相,除了药物,棺材也大有说法1hr1976年9月9日0时10分,毛主席在北京中南海逝世。在毛泽东纪念堂的瞻仰厅中,大厅正面白色大理石墙壁上镶嵌着鎏金隶书大字伟大的领袖和导师毛泽东主席永存不朽。在大厅中央,万花生死德比两结局,广州城靠外援广州看韦杨,郑智李玮峰谁才是一哥明晚广州对广州城德比之战,绝不亚于转天三镇打山东的爆裂,甚至还参杂些许悲情和残忍!为何说悲情?广州城少赛一场积6分,落后同城5分,如果胜将落后两分,保级主动将死死把握!而广州则被兄工行融e购商城关停银行电商路在何方?近日,工商银行接连发布融e购个人商城重要公告融e购企业商城重要公告,因业务调整,于6月30日2400停止其电商平台融e购个人商城相关服务,以及企业商城公开销售商圈销售跨境贸易等相关