快三绝密公式算单双:详解NodeJS Https HSM双向认证实现

北京快三走势图 www.mxld9.cn  更新时间:2019年03月12日 14:17:05   作者:githoniel   我要评论

这篇文章主要介绍了详解NodeJS Https HSM双向认证实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

工作中需要建立一套HSM的HTTPS双向认证通道,即通过硬件加密机(Ukey)进行本地加密运算的HTTPS双向认证,和银行的UKEY认证类似。

NodeJS可以利用openSSL的HSM plugin方式实现,但是需要编译C++,太麻烦,作者采用了利用Node Socket接口,纯JS自行实现Https/Http协议的方式实现

具体实现可以参考如下 node-https-hsm

TLS规范自然是参考RFC文档 The Transport Layer Security (TLS) Protocol Version 1.2

概述

本次TLS双向认证支持以下加密套件(*为建议使用套件):

  • TLS_RSA_WITH_AES_128_CBC_SHA256(TLS v1.2) *
  • TLS_RSA_WITH_AES_256_CBC_SHA256(TLS v1.2) *
  • TLS_RSA_WITH_AES_128_CBC_SHA(TLS v1.1)
  • TLS_RSA_WITH_AES_256_CBC_SHA(TLS v1.1)

四种加密套件流程完全一致,只是部分算法细节与报文略有差异,体现在

  • AES_128/AES_256的会话AES密钥长度分别为16/32字节。
  • TLS 1.1 在计算finish报文数据时,进行的是MD5 + SHA1的HASH算法,而在TLS v1.2下,HASH算法变成了单次SHA256。
  • TLS 1.1 处理finish报文时的伪随机算法(PRF)需要将种子数据为分两块,分别用 MD5 / SHA1 取HASH后异或,TLS 1.2 为单次 SHA256。
  • TLS 1.2 的 CertificateVerify / ServerKeyExchange 报文末尾新增2个字节的 Signature Hash Algorithm,表示 hash_alg 和 sign_alg。

目前业界推荐使用TLS v1.2, TLS v1.1不建议使用。

流程图

以下为 TLS 完整握手流程图

* =======================FULL HANDSHAKE======================
 * Client                        Server
 *
 * ClientHello         -------->
 *                         ServerHello
 *                         Certificate
 *                     CertificateRequest
 *               <--------   ServerHelloDone
 * Certificate
 * ClientKeyExchange
 * CertificateVerify
 * Finished           -------->
 *                     change_cipher_spec
 *               <--------       Finished
 * Application Data       <------->   Application Data

流程详解

客户端发起握手请求

TLS握手始于客户端发起 ClientHello 请求。

struct {
  uint32 gmt_unix_time; // UNIX 32-bit format, UTC时间
  opaque random_bytes[28]; // 28位长度随机数
} Random; //随机数

struct {
  ProtocolVersion client_version; // 支持的最高版本的TLS版本
  Random random; // 上述随机数
  SessionID session_id; // 会话ID,新会话为空
  CipherSuite cipher_suites<2..2^16-2>; // 客户端支持的所有加密套件,上述四种
  CompressionMethod compression_methods<1..2^8-1>; // 压缩算法
  select (extensions_present) { // 额外插件,为空
    case false:
      struct {};
    case true:
      Extension extensions<0..2^16-1>;
  };
} ClientHello; // 客户端发送支持的TLS版本、客户端随机数、支持的加密套件等信息

服务器端回应客户端握手请求

服务器端收到 ClientHello 后,如果支持客户端的TLS版本和算法要求,则返回 ServerHello, Certificate, CertificateRequest, ServerHelloDone 报文

struct {
  ProtocolVersion server_version; // 服务端最后决定使用的TLS版本
  Random random; // 与客户端随机数算法相同,但是必须是独立生成,与客户端毫无关联
  SessionID session_id; // 确定的会话ID
  CipherSuite cipher_suite; // 最终决定的加密套件
  CompressionMethod compression_method; // 最终使用的压缩算法
  select (extensions_present) { // 额外插件,为空
    case false:
      struct {};
    case true:
      Extension extensions<0..2^16-1>;
  };
} ServerHello; // 服务器端返回最终决定的TLS版本,算法,会话ID和服务器随机数等信息

struct {
  ASN.1Cert certificate_list<0..2^24-1>; // 服务器证书信息
} Certificate; // 向客户端发送服务器证书

struct {
  ClientCertificateType certificate_types<1..2^8-1>; // 证书类型,本次握手为 值固定为rsa_sign 
  SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; // 支持的HASH 签名算法
  DistinguishedName certificate_authorities<0..2^16-1>; // 服务器能认可的CA证书的Subject列表
} CertificateRequest; // 本次握手为双向认证,此报文表示请求客户端发送客户端证书

struct {

} ServerHelloDone // 标记服务器数据末尾,无内容

客户端收到服务器后响应

客户端应校验服务器端证书,通常用当用本地存储的可信任CA证书校验,如果校验通过,客户端将返回 Certificate, ClientKeyExchange, CertificateVerify, change_cipher_spec, Finished 报文。

CertificateVerify 报文中的签名为 Ukey硬件签名 , 此外客户端证书也是从Ukey读取。

struct {
  ASN.1Cert certificate_list<0..2^24-1>; // 服务器证书信息
} Certificate; // 向服务器端发送客户端证书

struct {
  select (KeyExchangeAlgorithm) {
    case rsa:
      EncryptedPreMasterSecret; // 服务器采用RSA算法,用服务器端证书的公钥,加密客户端生成的46字节随机数(premaster secret)
    case dhe_dss:
    case dhe_rsa:
    case dh_dss:
    case dh_rsa:
    case dh_anon:
      ClientDiffieHellmanPublic;
  } exchange_keys;
} ClientKeyExchange; // 用于返回加密的客户端生成的随机密钥(premaster secret)

struct {
  digitally-signed struct {
    opaque handshake_messages[handshake_messages_length]; // 采用客户端RSA私钥,对之前所有的握手报文数据,HASH后进行RSA签名
  }
} CertificateVerify; // 用于服务器端校验客户端对客户端证书的所有权

struct {
  enum { change_cipher_spec(1), (255) } type; // 固定值0x01
} ChangeCipherSpec; // 通知服务器后续报文为密文

struct {
  opaque verify_data[verify_data_length]; // 校验密文,算法PRF(master_secret, 'client finished', Hash(handshake_messages))
} Finished; // 密文信息,计算之前所有收到和发送的信息(handshake_messages)的摘要,加上`client finished`, 执行PRF算法

Finished 报文生成过程中,将产生会话密钥 master secret,然后生成Finish报文内容。

master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
verify_data = PRF(master_secret, 'client finished', Hash(handshake_messages))

PRF为TLS v1.2规定的伪随机算法, 此例子中,HMAC算法为 SHA256

PRF(secret, label, seed) = P_<hash>(secret, label + seed)

P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
            HMAC_hash(secret, A(2) + seed) +
            HMAC_hash(secret, A(3) + seed) + ...
// A(0) = seed
// A(i) = HMAC_hash(secret, A(i-1))

服务器完成握手

服务收到请求后,首先校验客户端证书的合法性,并且验证客户端证书签名是否合法。根据服务器端证书私钥,解密 ClientKeyExchange,获得pre_master_secret, 用相同的PRF算法即可获取会话密钥,校验客户端 Finish 信息是否正确。如果正确,则服务器端与客户端完成密钥交换。 返回 change_cipher_spec, Finished 报文。

struct {
  enum { change_cipher_spec(1), (255) } type; // 固定值0x01
} ChangeCipherSpec; // 通知服务器后续报文为密文

struct {
  opaque verify_data[verify_data_length]; // 校验密文,算法PRF(master_secret, 'server finished', Hash(handshake_messages))
} Finished; // 密文信息,计算之前所有收到和发送的信息(handshake_messages)的摘要,加上`server finished`, 执行PRF算法

客户端会话开始

客户端校验服务器的Finished报文合法后,握手完成,后续用 master_secret 发送数据。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • nodejs连接mysql数据库及基本知识点详解

    nodejs连接mysql数据库及基本知识点详解

    这篇文章主要介绍了nodejs连接mysql数据库,结合实例形式总结分析了nodejs连接与操作mysql数据库的相关模板、配置及mysql数据库查询、添加数据等操作技巧,需要的朋友可以参考下
    2018-03-03
  • Node.js实现的简易网页抓取功能示例

    Node.js实现的简易网页抓取功能示例

    这篇文章主要介绍了Node.js实现的简易网页抓取功能示例,本文使用了PhantomJS、node-phantomjs等库实现,需要的朋友可以参考下
    2014-12-12
  • node.js express安装及示例网站搭建方法(分享)

    node.js express安装及示例网站搭建方法(分享)

    下面小编就为大家带来一篇node.js express安装及示例网站搭建方法(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • sublime text配置node.js调试(图文教程)

    sublime text配置node.js调试(图文教程)

    下面小编就为大家分享一篇sublime text配置node.js调试(图文教程),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • 详解node单线程实现高并发原理与node异步I/O

    详解node单线程实现高并发原理与node异步I/O

    本篇文章主要介绍了node单线程实现高并发原理与node异步I/O ,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • 基于nodejs实现微信支付功能

    基于nodejs实现微信支付功能

    这篇文章主要为大家详细介绍了基于nodejs实现微信支付功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • NodeJS实现客户端js加密

    NodeJS实现客户端js加密

    本文主要介绍了NodeJS实现客户端js加密的思路与方法,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • node.js操作mongoDB数据库示例分享

    node.js操作mongoDB数据库示例分享

    这里给大家分享的是node.js操作mongoDB数据库的示例,包括连接数据库、插入数据、关闭数据库、读取数据、插入数据等方面,十分的全面,这里推荐给需要的小伙伴们。
    2014-11-11
  • express的中间件bodyParser详解

    express的中间件bodyParser详解

    这篇文章主要介绍了node.js中express的中间件bodyParser的使用方法,需要的朋友可以参考下
    2014-12-12
  • node.js中的fs.readdirSync方法使用说明

    node.js中的fs.readdirSync方法使用说明

    这篇文章主要介绍了node.js中的fs.readdirSync方法使用说明,本文介绍了fs.readdirSync方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12

最新评论

  • 解说米勒谈WE:LPL夏季赛夺冠可能性不大 2019-05-23
  • 陈坤:虽然会被困扰,但感谢情绪无法删除 2019-05-22
  • 问题来了!那些年你遇到的噪声扰民怎么办? 2019-05-21
  • 俞正声:广泛开展对外友好交往 2019-05-21
  • 运用互联网思维介入城市化会如何? 2019-05-20
  • 【加拿大房产网加拿大新房加拿大房产信息网】 2019-05-20
  • 银保监会新规剑指大企业多头融资和过度融资 2019-05-19
  • [网连中国]5地社保费率降低后工资条看变化 职工:只少交几块钱 2019-05-19
  • 全国政协委员侯一筠:发挥山东海洋优势,打造国家级科技成果转化平台 2019-05-18
  • 广西河池消防支队召开新兵第二阶段集训工作部署会 2019-05-18
  • 龙峰:帮助更多企业用好互联网—上游新闻对话重庆经济 2019-05-17
  • 其实,生产力发展了,社会财富丰富了,把小萌们养起来也不是什么问题……但你们不能被养着还养出脾气来还妄图对真正的劳动者指手画脚! 2019-05-16
  • 全国人大代表、三角轮胎董事长丁玉华去世 2019-05-15
  • 省国资委党委召开省属企业党风廉政建设和反腐败工作会议 2019-05-14
  • 请问,建立市场经济后,原计划经济哪里去?改革后,我们还在实行计划经济,为何没有提及? 2019-05-14
  • 953| 201| 324| 698| 64| 905| 711| 919| 682| 602|