摘要:华为云IoT设备接入云服务(后续章节简称为“IoTDA”)提供海量设备的接入和管理能力,可以将IoT设备联接到华为云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助快速构筑物联网解决方案。

本文分享自华为云社区《大型物联网平台如何来保障亿级设备安全连接上云?》,作者:华为云IoT高级工程师茂茂。

1. IoTDA业务流

华为云IoT设备接入云服务(后续章节简称为“IoTDA”)提供海量设备的接入和管理能力,可以将IoT设备联接到华为云,支撑设备数据采集上云和云端下发命令给设备进行远程控制,配合华为云其他产品,帮助快速构筑物联网解决方案。

使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。

其中,业务应用又可拆解为应用集成层设备数据集成层两部分,前者基于IoTDA提供的丰富的原子API实现设备管理和控制,后者基于IoTDA提供数据流转能力实现设备数据采集。

通过上述分析,在IoTDA的业务流中,存在多个交互过程,包括但不限于:①应用集成层与平台、②设备与平台、③平台与设备数据集成层。

交互必然存在认证鉴权,此文以上述三个交互过程为例,对IoTDA的鉴权和认证进行分析,帮助开发者理解其中的安全原理和机制,快速上手华为云IoT设备接入云服务。

2. 认证鉴权基本概念

在进入IoTDA业务流认证鉴权前,首先,我们要先理解“认证鉴权”这一概念。

这里我们引入一个例子,帮助我们快速理解。唐三藏西天取经,路过一个个关隘,过程我们很熟悉了——唐三藏递送通关文牒,口念:“贫僧唐三藏,从东土大唐而来,去往西天拜佛求经”。

对应着我们的哲学三问:

  1. 我是谁?(贫僧唐三藏)
  2. 我从哪里来?(从东土大唐而来)
  3. 我要到哪里去?(去往西天拜佛求经)

声明了自己的身份以及执行的操作。

关隘把守人员:

  1. 验证身份:他是不是东土大唐派来的唐三藏?——认证(凭据为通关文牒)。
  2. 东土大唐派遣(委托)唐三藏去西天取经,凭据为通关文牒。——授权(授权媒介为通关文牒)
  3. 通关文牒中派遣是否真实?——鉴权(通关文牒的真实性)
  4. 要不要放他通行?——权限控制(通关)

说明:如下关于“认证、授权、鉴权、权限控制”的内容来自对互联网相关资料的整理。

2.1 认证(Identification)

访问系统的主体身份进行验证的过程,确认访问主体是它所声明的。访问主体使用**“身份标识符+认证凭证”**来证明自己的身份。

一般来说,认证有三种方式:

  • 基于信息秘密的身份认证,你知道的内容(something you know):静态口令、预共享密钥、公私钥对、数字证书…
  • 基于信任物体的身份认证,你持有的证明(something you have):智能卡、动态令牌卡(u盾)、身份证…
  • 基于生物特征的身份认证,你就是这个人(something you are):生物特征(虹膜、面部、指纹、语音等)

高安全要求的场景下,会使用多种认证方式组合进行身份校验,即多因素认证。

2.2 授权(Authorization)

资源所有者委派执行者,赋予其指定范围的权限,执行对资源的操作。

资源所有者:拥有资源的所有权利,一般就是资源的拥有者。

执行者:被委派去执行资源的相关操作。

操作权限:可以对资源进行的某种操作。

资源:有价值的信息或数据等,受到安全保护。

现实生活中,授权的实现方式(授权媒介)有银行卡、门禁卡、钥匙、证书等,在互联网应用开发领域,授权的实现方式有:

  • 通过web服务器的session机制,一个访问会话保持着用户的授权信息
  • 通过web浏览器的cookie机制,一个网站的cookie保持着用户的授权信息
  • 颁发授权令牌(token),一个合法有效的令牌中保持着用户的授权信息

通常要求授权媒介不可被篡改,不可随意伪造,很多时候需要受保护,防止被窃取。

2.3 鉴权(Authentication)

对一个声明者的身份权利的真实性进行鉴别。

授权和鉴权是一个一一对应的流程,有授权才会去鉴权,鉴权就是对授权所颁发授信媒介进行解析,确认其真实性。

2.4 权限控制(Access/Permission Control)

权限控制是指对可执行的各种操作组合配置为权限列表,然后根据执行者的权限,若其操作在权限范围内,则允许执行,否则禁止。

权限,是将执行者的行为抽象化的一个概念。

控制,是根据执行者的权限,对其所执行的操作进行判断,决定允许或禁止当前操作的执行。

常见的权限系统设计模型有DAC(Discretionary Access Control)自主访问控制、MAC(mandatory access control)强制访问控制、RBAC(Role-Based Access Control)基于角色的访问控制、ABAC(Attribute-based access control)基于属性的访问控制。

2.5 四者的关系

认证、授权、鉴权和权限控制这四个环节是一个前后依次发生、上下游的关系:认证-->授权-->鉴权-->权限控制。

认证和授权经常同时发生,让人误以为两者一样,其实两者是不一样的概念,两者都有对身份的确认过程,主要区别在于:

  • 认证是确认声明者的本身身份,其作为授权的上游衔接而存在;
  • 鉴权是对声明者所声明的真实性进行确认的过程,其作为授权的下游衔接而存在。

3. 通用的认证鉴权手段

“基于信息秘密的身份认证”的这一类认证方式较为常见,本文涉及的认证手段均属此类。

服务端对客户端的认证鉴权要解决两个关键问题:

  1. 确认客户端的身份;
  2. 确认请求来自确定身份的客户端。

3.1 基于账号口令认证鉴权:

客户端和服务端均持有认证客户端的账号口令,客户端认证和鉴权过程均携带账号口令,服务端通过验证账号口令的正确性来完成认证和鉴权。

此种方式需要保证口令存储和传输过程的秘密性,不被服务端和客户端以外的第三方窃取。一旦口令遭到泄露,客户端身份将有可能被仿冒,在更新泄露的口令前都始终存在极大的安全隐患。因此,我们很容易想到给凭据增加一个期限。

3.2 临时令牌鉴权:

与“基于账号口令认证鉴权”相同,客户端和服务端预共享账号口令,认证过程中,客户端携带账号口令,服务端验证账号口令的正确性。不同的是,认证通过后,服务端向客户端下发有一定时效性的令牌即Token,客户端在令牌有效期内使用该临时令牌与服务端进行业务交互,服务端基于该Token对客户端进行鉴权。

在鉴权阶段使用有时效性的凭据,可有效避免口令在鉴权阶段的泄露。此种方式仍然需要保证口令存储和认证传输过程中的秘密性,同时也需要保证临时令牌在时效内的秘密性,一定程度上降低了口令泄露的概率。

3.3 对称加密认证:

与前两者类似,客户端和服务端预共享账号口令。认证和鉴权过程中,客户端使用口令作为加密秘钥对请求或请求的摘要做加密,将密文附加在认证和鉴权的请求中,服务端收到请求后,使用口令对密文做解密或对摘要做验证,随即完成对客户端的认证和鉴权。

此种方式仍需保证口令存储的秘密性,但可喜的是实现了口令不出现在传输过程中,显著降低了口令泄露的风险。

账号和口令是客户端身份的象征,谁持有了该客户端的账号和口令就被认为是该客户端。客户端的账号口令本应只属于客户端所有,但因服务端的验证需要,客户端需与服务端共享该账号及口令。若有一种验证方式,能够实现服务端不持有口令即可完成口令的验证,那么将带来安全性的跨越式提升。

3.4 非对称加密认证:

非对称加密应运而生。客户端生成一对唯一的密钥对,密钥对包含一个公钥和一个私钥,两者一一对应,秘钥对有如下属性:密钥对包含公钥和私钥,如果用其中一个密钥加密一段数据,则必须用另一个密钥才能解密

在“对称加密认证”的基础上,客户端与服务端预共享公钥。认证和鉴权过程中,客户端使用私钥对请求或请求的摘要加密,将密文附加在认证和鉴权的请求中,服务端收到请求后,使用公钥对密文解密或对摘要做验证,随即完成对客户端的认证和鉴权。当服务端需要给客户端回复信息时,服务端可使用公钥对信息加密,该信息也只能由客户端的私钥解密。

如上过程我们可总结为:”公钥共享,私钥保密;公钥加密,私钥解密;私钥签名,公钥验签“。只要客户端不泄露私钥,那么就是安全的。

此种方式仅需保证私钥在客户端端存储的秘密性,同时也可实现整个端到端通信过程的安全可信。

3.5 证书认证:

前一种方式下,若存在大量的客户端,那么预共享公钥显然会是个繁琐的过程。

好在办法总比困难多。信任模型能够解决“大量客户端”与服务端预共享公钥的问题。

具体的做法是:我们对公钥做一个变身,公钥叠加客户端身份信息得到TBS(to be signed),引入一个可信的第三方负责对客户端身份信息做公证(可信第三方使用其私钥对TBS签名,将TBS、签名算法及签名值组合而成得到证书),认证和鉴权过程中,客户端将证书传输给服务端,服务端仅需通过预共享可信第三方的公钥,使用该公钥验证证书并提取到客户端身份信息、服务端公钥,即可完成对客户端公钥的预共享,随即可完成后续的认证和鉴权。

如上过程我们可以理解为:预共享客户端公钥的目的是将身份标识及对应的公钥提供给服务端,证书方式将此过程交给可信第三方完成,服务端从客户端提供的证书中提取这两种信息,这两种信息的真实性通过可信第三方的公证(对证书验签)来保证。

如果客户端私钥遭泄露怎么办?那么就引入了吊销机制。

可信第三方维护了一个被吊销了的客户端证书列表,并将该列表获取方式附加在它所颁发的证书的扩展信息中;客户端一旦泄露自身私钥,则向可信第三方申请吊销该证书;申请通过后可信第三方将该证书添加到证书吊销列表中。服务端在验证客户端证书时,从证书中读取证书吊销列表获取方式,从而获取到已吊销的证书列表,确认该证书是否已被吊销,实际实现中为了避免性能消耗,服务端定期从可信第三方获取吊销证书列表并做缓存,每次比对仅需在缓存中比对,无需频繁从可信第三方拉取吊销列表。

3.6 双向证书认证:

前一小节介绍了服务端对客户端的认证,客户端认证服务端,也只需要在客户端预置服务端的证书CA,即可实现双向证书认证。

双向证书认证是一种使用数字证书作为通信实体身份鉴别依据的认证手段。基于:

  1. 非对称加密特性:密钥对包含公钥和私钥,如果用其中一个密钥加密一段数据,则必须用另一个密钥才能解密。”公钥共享,私钥保密;公钥加密,私钥解密;私钥签名,公钥验签“。
  2. 数字证书:包含一个公钥、身份信息以及证书授权中心的数字签名。
  3. 信任模型:当可以确定一个实体身份或者有一个足够可信的身份签发者证明该实体的身份时,才能做出信任那个身份的决定。

举个例子,来自中国的张三要和来自美国的David通信,在会话建立前双方都需要确认对方的身份(张三:对方是不是美国的David?David:对方是不是中国的张三?)。

张三来自中国,身份由ca_china.crt颁发,David来自USA,身份由ca_usa.crt颁发。张三要确认David的身份,需要使用ca_usa.crt来验证其身份,反之,David需要确认张三的身份,需要使用ca_china.crt来确认张三的身份。通信双方均使用ca认证对端为双向认证,仅一方认证另一方,为单向认证。

4. IoTDA提供的多种认证手段

4.1 应用集成层与平台

这部分的业务流程为应用调用平台提供的应用侧API来实现。平台针对向应用提供的应用侧API封装了多种编程界面:

  • Console:即华为云官网控制台(以下简称“Console”),为Web界面,最大的优点是无需任何编程基础,非常直观,租户进行通过浏览器输入账号密码,登陆华为云控制台,即可实现Console上的业务操作。
  • 华为云SDK V3:华为云简单易学、隐藏细节、多语言支持;
  • API Explorer:快速检索,在线调试,联动文档;
  • CLI:独立执行、多OS平台、自动升级;
  • 自行封装:提供java语言的样例(支持apache-httpclient和okhttp)。

认证方式有账号密码访问秘钥两种,均为“基于信息秘密的身份认证”,就使用的授权媒介(或称为鉴权依据)而言,前者为Token,后者为签名。账号密码不做过多赘述,此处重点介绍访问秘钥。

4.1.1 访问秘钥

4.1.1.1 永久安全凭证

文档首页> 统一身份认证服务 IAM> 用户指南> IAM用户> 管理IAM用户访问密钥

管理IAM用户访问密钥_统一身份认证服务 IAM_用户指南_IAM用户_华为云

访问密钥即AK/SK(Access Key ID/Secret Access Key),是您通过开发工具(API、CLI、SDK)访问华为云时的身份凭证,不能登录控制台。系统通过AK识别访问用户的身份,通过SK进行签名验证,通过加密签名验证可以确保请求的机密性、完整性和请求者身份的正确性。

“永久安全凭据”又称“访问秘钥”,也称“AK/SK”。

4.1.1.2 临时安全凭证

为满足客户对安全的时效性需要,华为云提供了与永久安全凭证相对应的临时安全凭证,其中包括临时AK/SK和SecurityToken。临时安全凭证与永久安全凭证的工作方式几乎相同,仅存在小量差异。

4.1.1.3 安全凭证签名过程

签名过程为:

文档首页> API签名指南> API签名指南> 概述

概述_API签名指南_API签名指南_华为云

  1. 构造规范请求
    CanonicalRequest =
    HTTPRequestMethod + '\n' +
    CanonicalURI + '\n' +
    CanonicalQueryString + '\n' +
    CanonicalHeaders + '\n' +
    SignedHeaders + '\n' +
    HexEncode(Hash(RequestPayload))

HashedCanonicalRequest = Lowercase(HexEncode(Hash.SHA256(CanonicalRequest)))

  1. 创建待签字符串
    StringToSign =
    Algorithm + \n +
    RequestDateTime + \n +
    HashedCanonicalRequest
  2. 计算签名
    signature = HexEncode(HMAC(Secret Access Key, StringToSign))
  3. 添加签名信息到请求头
    Authorization: algorithm Access=Access key, SignedHeaders=SignedHeaders, Signature=signature

4.1.2 用户界面

图形界面:

  • Console:通过浏览器输入账号密码;
  • API Explorer:通过浏览器输入账号密码;

调试工具:

  • CLI:AK/SK;
  • Postman:Token

编程界面:

  • 华为云SDK V3:AK/SK;
  • 自封装:提供java语言的样例(支持apache-httpclient和okhttp)。

在业务实践过程中,多数客户对华为云SDK V3青睐有加,极少数客户选择自封装的方式。本章节对这两种方式做一个java语言版本的演示。

4.1.2.1 华为云SDK V3(推荐)

Java SDK使用指南_设备接入 IoTDA_SDK参考_应用侧SDK_华为云

方式一:使用通用认证类(BasicCredentials)

// 基础版地址List<String> basicEndpoints = Arrays.asList("https://iotda.cn-north-4.myhuaweicloud.com","https://4e1af840db.iotda.cn-north-4.myhuaweicloud.com");// 创建认证ICredential auth = new BasicCredentials().withAk(ak).withSk(sk).withDerivedPredicate(new Function<HttpRequest, Boolean>() {@Overridepublic Boolean apply(HttpRequest httpRequest) {// 根据endpoint判断需要使用何种签名方式// 基础版使用AKSK鉴权方式,此处返回false;// 非基础版需要使用衍生AKSK鉴权方式,此处返回trueString endpoint = httpRequest.getEndpoint();return !basicEndpoints.contains(endpoint);}});// 创建IoTDAClient实例并初始化IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)// 基础版:请选择IoTDARegion中的Region对象//.withRegion(IoTDARegion.CN_NORTH_4)// 标准版/企业版:需自行创建Region对象.withRegion(new Region(REGION_ID, ENDPOINT)).build();

方式二:使用IoTDA的专属鉴权类(IoTDACredentials)

// *********************** 访问基础版 ***********************// 创建认证ICredential auth = new IoTDACredentials().withAk(ak).withSk(sk).withDefaultEndpoint(true); // 标准基础版,此处设置为 true// 创建IoTDAClient实例并初始化IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)// 基础版:请选择IoTDARegion中的Region对象.withRegion(IoTDARegion.CN_NORTH_4).build();
​
​// *********************** 访问标准版/企业版 ***********************
​    // 创建认证
​    ICredential auth = new IoTDACredentials()
​            .withAk(ak)
​            .withSk(sk)
​            .withDefaultEndpoint(false); // 标准标准版/企业版,此处设置为 false
​    // 创建IoTDAClient实例并初始化IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)// 标准版/企业版:需自行创建Region对象.withRegion(new Region(REGION_ID, ENDPOINT)).build();
​
​// *********************** 通过内部网络组件访问基础版 ***********************
​    // 创建认证
​    ICredential auth = new IoTDACredentials()
​            .withAk(ak)
​            .withSk(sk)
​            .withDefaultEndpoint(true); // 标准基础版,此处设置为 true
​    // 创建IoTDAClient实例并初始化IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)// 标准版/企业版:需自行创建Region对象.withRegion(new Region(REGION_ID, "https://internl-nginx:8080")).build();

4.1.2.2 自封装(存量系统使用)

提供Java版本的Example:

Java Demo使用说明_设备接入 IoTDA_开发指南_应用侧开发_华为云

AKSK认证

/*********************** AKSK认证 ***********************/// 初始化基础版信息。默认以 `https://iotda.cn-north-4.myhuaweicloud.com` 为基础版,
// 若某些情况(例如客户端与平台之间通过客户自身内网网络组件转发)下基础版地址有变化,则可通过如下方法添加:
// ClientExt.addBasicEndpoint("https://custom-proxy.endpoint:443");
// ClientExt.addBasicEndpoint("http://custom-proxy.endpoint:8080");
// ClientExt.addBasicEndpoint("http://172.1.2.3:8080");
// ClientExt.addBasicEndpoint("https://172.1.2.3:1883");// 构造请求
Request request = new Request();
request.setKey(Constants.ACCESS_KEY);
request.setSecret(Constants.SECRET_KEY);
// ... 设置url、headers、method、requestBody等// 签名(此处对基础版和标准版/企业版做了兼容性处理)
HttpRequest httpRequest = ClientExt.sign(regionId, request);// ... 发送请求
HttpResponse httpResponse = httpUtils.execute(httpRequest);

Token认证(需自行管理Token的生命周期

/*********************** Token认证 ***********************/
// ... 设置url、headers、method、requestBody等
HttpRequest httpRequest = buildHttpRequest();// 设置Token(需自行解决Token过期或失效时的轮换问题)
header.put("X-Auth-Token", token);// ... 发送请求
HttpResponse httpResponse = httpUtils.execute(httpRequest);

4.2 设备与平台

平台提供X.509证书双向认证和秘钥认证两种设备侧认证方式。客户可根据设备的能力和实际业务需要自行选择。

4.2.1 X.509证书双向认证

证书双向认证完整业务流程为:

证书双向认证过程为:

4.2.2 密钥认证

/*** HmacSHA256** @param str       输入字符串* @param timeStamp 时间戳* @return hash后的字符串*/public static String sha256_mac(String str, String timeStamp) {String passWord = null;try {Mac sha256Hmac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKey = new SecretKeySpec(timeStamp.getBytes("UTF-8"), "HmacSHA256");sha256Hmac.init(secretKey);byte[] bytes = sha256Hmac.doFinal(str.getBytes("UTF-8"));passWord = byteArrayToHexString(bytes);} catch (Exception e) {log.error(ExceptionUtil.getBriefStackTrace(e));}return passWord;}

4.3 平台与设备数据集成层

当前华为物联网平台支持HTTP/HTTPS和AMQP两种订阅方式,未来还将支持MQTT订阅方式。

4.3.1 HTTP/HTTPS

第三方应用服务(HTTP推送):应用服务器通过调用物联网平台的创建规则触发条件、创建规则动作、修改规则触发条件接口配置并激活规则,在指定应用服务器的URL后,将平台获取发生变更的设备业务信息(如设备生命周期管理、设备数据上报、设备消息状态、设备状态等)和管理信息(软固件升级状态和升级结果)推送给指定URL的服务器。

Https方式:使用证书双向认证,IoT平台加载由客户提供的用于认证应用服务器证书的CA证书。与之对应的,作为服务端,应用侧如果需要认证IoT平台的身份,需要加载IoT平台的CA证书。

4.3.2 AMQP

用户侧使用平台为其生成的accessKey/accessCode作为认证凭据,与IoT平台建立长链接,实现数据拉取和推送以实现数据集成。

更多学习内容,请前往IoT物联网社区 

华为伙伴暨开发者大会2022火热来袭,重磅内容不容错过!

【精彩活动】

勇往直前·做全能开发者→12场技术直播前瞻,8大技术宝典高能输出,还有代码密室、知识竞赛等多轮神秘任务等你来挑战。即刻闯关,开启终极大奖!点击踏上全能开发者晋级之路吧!

【技术专题】

未来已来,2022技术探秘→华为各领域的前沿技术、重磅开源项目、创新的应用实践,站在智能世界的入口,探索未来如何照进现实,干货满满点击了解

点击关注,第一时间了解华为云新鲜技术~

大型物联网平台如何来保障亿级设备安全连接上云?相关推荐

  1. 大型 IoT 物联网平台如何保障亿级设备安全连接上云?

    01. 华为云 IoTDA业务流 华为云IoT设备接入云服务(简称"IoTDA")提供海量设备的接入和管理能力,可以将IoT设备联接到华为云,支撑设备数据采集上云和云端下发命令给设 ...

  2. 亿级日PV的魅族云同步的核心协议与架构实践

    声明:本文根据msup和魅族联合举办的<第三期魅族技术开放日-架构设计与优化>录音整理原创首发,转载或节选内容前需获授权.  嘉宾:沈辉煌,魅族高级架构师,魅族云同步负责人.2010年加入 ...

  3. 揭秘 | 阿里云IoT物联网平台亿级设备接入方案大揭秘

    一.前言 不同的接入层 互联网的产品基本都需要解决终端的接入问题,每个接入层会因为终端数量.终端能力.网络环境等不同的因素有各自的设计特性,比如:淘宝网需要解决海量短连接问题.微信需要解决海量长连接问 ...

  4. 蚂蚁金服黑科技:SOFA DTX分布式事务,保障亿级资金操作一致性

    原文链接:点击打开链接 摘要: 小蚂蚁说: SOFA ( Scalable Open Financial Architecture )是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构 ...

  5. 千亿级市场赛道,阿里云视频云拿下 “三连冠”

    简介:阿里云视频云市场份额 全球权威咨询机构 IDC 发布 <中国视频云市场跟踪(2020 下半年)>报告: 阿里云连续三年 稳居视频云整体市场份额第一 整体市场份额占比达 26.21% ...

  6. 巧用 maxTimeMS 服务端超时,避免承载亿级用户的腾讯云数据库MongoDB服务雪崩

    腾讯云数据库MongoDB作为一款基于开源社区MongoDB版本的文档数据库产品,其承载着公司内外包括微信.看点.QQ音乐在内的亿级用户重量级APP产品.在某些场景的使用过程中,用户在客户端请求超时后 ...

  7. mqtt 域名连接_中国移动OneNet物联网平台,如何使用MQTT协议,进行连接

    大家好,超子又和大家见面了,超子我能力有限,技术不高,有什么错误的地方,欢迎板砖.今天我们一起构建MQTT协议中的CONNECT报文,连接OneNet物联网平台,然后进行通信.前面的文章中,超子介绍阿 ...

  8. 【无标题】关于BC25连接电信物联网平台的问题(批量产品在广东连接不到物联网平台,在合肥测试是可以的)

    现象: 在合肥测试的时候连接物联网平台是OK的,但是在广东的代工厂却连接不上电信物联网平台 排除 硬件以及信号的问题,以及查询卡的状态是OK正常的,排除卡的区域限制的业务功能,就是不行,Debug调试 ...

  9. 【阿里云物联网平台-1】使用MQTTfx模拟客户端,往阿里云物联网平台发布数据

    目录 MQTT协议简单介绍(每句都是干货) 手把手流程 服务器:阿里云物联网平台 客户端:MQTTfx 后记 MQTT协议简单介绍(每句都是干货) MQTT是应用层协议,基于TCP/IP. 是一种发布 ...

最新文章

  1. 调整Win7资源管理器中导航栏和计算机的位置
  2. Java设计模式(十一):组合设计模式
  3. 10 个 GitHub 上超火和超好看的管理后台模版,后台管理项目有着落了
  4. Ciel and Robot CodeForces - 322C
  5. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3
  6. 小程序弹框出现,底部页面也跟随滚动
  7. C++ 获取std::vector 长度 大小
  8. 用Intel线程构建块进行安全、可伸缩性的并行编程
  9. (转)对冲基金投身“另类数据”淘金热
  10. 软考信息安全工程师教程第二版
  11. 华为虚拟机eNSP命令大全
  12. linux降内核版本_linux内核降级
  13. android随机抽奖代码_Android 中从一个集合或者数组中随机抽取几个不同的值
  14. R语言绘图|二维数据密度图
  15. 计算机教师计算机网络面试题,初中信息技术教师资格面试真题及答案:IP地址...
  16. leetcode#246 中心对称数
  17. 云烟成雨,我多想再见你,
  18. Python爬取微博短视频
  19. 静态网页之--小说阅读网
  20. 西储大学轴承数据小波变换

热门文章

  1. vue引用qrcodejs2生成、下载二维码、复制到剪贴板
  2. linux欧拉强制修改root密码,openEuler 20.03 LTS安装图文教程
  3. Matcher 详解
  4. h5的audio自定义样式(转)
  5. HP CQ42 221AX 笔记本Win7 XP双系统安装成功经历
  6. Python的作者及简介
  7. linux yum 安装 htop,CentOS6.7 htop安装
  8. 轻松实现对pdf文件编辑修改
  9. ## 服务器端口开放教程+windows防火墙无法更改某些设置 错误代码0X8007解决方案
  10. java基本语法循环语句 —for循环