最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解NodeJS Https HSM雙向認證實現(xiàn)

 更新時間:2019年03月12日 14:17:05   作者:githoniel  
這篇文章主要介紹了詳解NodeJS Https HSM雙向認證實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

工作中需要建立一套HSM的HTTPS雙向認證通道,即通過硬件加密機(Ukey)進行本地加密運算的HTTPS雙向認證,和銀行的UKEY認證類似。

NodeJS可以利用openSSL的HSM plugin方式實現(xiàn),但是需要編譯C++,太麻煩,作者采用了利用Node Socket接口,純JS自行實現(xiàn)Https/Http協(xié)議的方式實現(xiàn)

具體實現(xiàn)可以參考如下 node-https-hsm

TLS規(guī)范自然是參考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)

四種加密套件流程完全一致,只是部分算法細節(jié)與報文略有差異,體現(xiàn)在

  • AES_128/AES_256的會話AES密鑰長度分別為16/32字節(jié)。
  • TLS 1.1 在計算finish報文數(shù)據(jù)時,進行的是MD5 + SHA1的HASH算法,而在TLS v1.2下,HASH算法變成了單次SHA256。
  • TLS 1.1 處理finish報文時的偽隨機算法(PRF)需要將種子數(shù)據(jù)為分兩塊,分別用 MD5 / SHA1 取HASH后異或,TLS 1.2 為單次 SHA256。
  • TLS 1.2 的 CertificateVerify / ServerKeyExchange 報文末尾新增2個字節(jié)的 Signature Hash Algorithm,表示 hash_alg 和 sign_alg。

目前業(yè)界推薦使用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

流程詳解

客戶端發(fā)起握手請求

TLS握手始于客戶端發(fā)起 ClientHello 請求。

struct {
  uint32 gmt_unix_time; // UNIX 32-bit format, UTC時間
  opaque random_bytes[28]; // 28位長度隨機數(shù)
} Random; //隨機數(shù)

struct {
  ProtocolVersion client_version; // 支持的最高版本的TLS版本
  Random random; // 上述隨機數(shù)
  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; // 客戶端發(fā)送支持的TLS版本、客戶端隨機數(shù)、支持的加密套件等信息

服務(wù)器端回應(yīng)客戶端握手請求

服務(wù)器端收到 ClientHello 后,如果支持客戶端的TLS版本和算法要求,則返回 ServerHello, Certificate, CertificateRequest, ServerHelloDone 報文

struct {
  ProtocolVersion server_version; // 服務(wù)端最后決定使用的TLS版本
  Random random; // 與客戶端隨機數(shù)算法相同,但是必須是獨立生成,與客戶端毫無關(guān)聯(lián)
  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; // 服務(wù)器端返回最終決定的TLS版本,算法,會話ID和服務(wù)器隨機數(shù)等信息

struct {
  ASN.1Cert certificate_list<0..2^24-1>; // 服務(wù)器證書信息
} Certificate; // 向客戶端發(fā)送服務(wù)器證書

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>; // 服務(wù)器能認可的CA證書的Subject列表
} CertificateRequest; // 本次握手為雙向認證,此報文表示請求客戶端發(fā)送客戶端證書

struct {

} ServerHelloDone // 標記服務(wù)器數(shù)據(jù)末尾,無內(nèi)容

客戶端收到服務(wù)器后響應(yīng)

客戶端應(yīng)校驗服務(wù)器端證書,通常用當用本地存儲的可信任CA證書校驗,如果校驗通過,客戶端將返回 Certificate, ClientKeyExchange, CertificateVerify, change_cipher_spec, Finished 報文。

CertificateVerify 報文中的簽名為 Ukey硬件簽名 , 此外客戶端證書也是從Ukey讀取。

struct {
  ASN.1Cert certificate_list<0..2^24-1>; // 服務(wù)器證書信息
} Certificate; // 向服務(wù)器端發(fā)送客戶端證書

struct {
  select (KeyExchangeAlgorithm) {
    case rsa:
      EncryptedPreMasterSecret; // 服務(wù)器采用RSA算法,用服務(wù)器端證書的公鑰,加密客戶端生成的46字節(jié)隨機數(shù)(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私鑰,對之前所有的握手報文數(shù)據(jù),HASH后進行RSA簽名
  }
} CertificateVerify; // 用于服務(wù)器端校驗客戶端對客戶端證書的所有權(quán)

struct {
  enum { change_cipher_spec(1), (255) } type; // 固定值0x01
} ChangeCipherSpec; // 通知服務(wù)器后續(xù)報文為密文

struct {
  opaque verify_data[verify_data_length]; // 校驗密文,算法PRF(master_secret, 'client finished', Hash(handshake_messages))
} Finished; // 密文信息,計算之前所有收到和發(fā)送的信息(handshake_messages)的摘要,加上`client finished`, 執(zhí)行PRF算法

Finished 報文生成過程中,將產(chǎn)生會話密鑰 master secret,然后生成Finish報文內(nèi)容。

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規(guī)定的偽隨機算法, 此例子中,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))

服務(wù)器完成握手

服務(wù)收到請求后,首先校驗客戶端證書的合法性,并且驗證客戶端證書簽名是否合法。根據(jù)服務(wù)器端證書私鑰,解密 ClientKeyExchange,獲得pre_master_secret, 用相同的PRF算法即可獲取會話密鑰,校驗客戶端 Finish 信息是否正確。如果正確,則服務(wù)器端與客戶端完成密鑰交換。 返回 change_cipher_spec, Finished 報文。

struct {
  enum { change_cipher_spec(1), (255) } type; // 固定值0x01
} ChangeCipherSpec; // 通知服務(wù)器后續(xù)報文為密文

struct {
  opaque verify_data[verify_data_length]; // 校驗密文,算法PRF(master_secret, 'server finished', Hash(handshake_messages))
} Finished; // 密文信息,計算之前所有收到和發(fā)送的信息(handshake_messages)的摘要,加上`server finished`, 執(zhí)行PRF算法

客戶端會話開始

客戶端校驗服務(wù)器的Finished報文合法后,握手完成,后續(xù)用 master_secret 發(fā)送數(shù)據(jù)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node.js通過Sequelize 連接MySQL的方法

    node.js通過Sequelize 連接MySQL的方法

    這篇文章主要介紹了node.js通過Sequelize 連接MySQL的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • nodejs 十六進制字符串型數(shù)據(jù)與btye型數(shù)據(jù)相互轉(zhuǎn)換

    nodejs 十六進制字符串型數(shù)據(jù)與btye型數(shù)據(jù)相互轉(zhuǎn)換

    這篇文章主要介紹了nodejs 十六進制字符串型數(shù)據(jù)與btye型數(shù)據(jù)相互轉(zhuǎn)換,需要的朋友可以參考下
    2018-07-07
  • NodeJs之word文件生成與解析的實現(xiàn)代碼

    NodeJs之word文件生成與解析的實現(xiàn)代碼

    這篇文章主要介紹了NodeJs之word文件生成與解析的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 教你如何使用node.js制作代理服務(wù)器

    教你如何使用node.js制作代理服務(wù)器

    本文介紹了如何使用node.js制作代理服務(wù)器,圖文并茂,十分的詳細,代碼很簡潔易懂,這里推薦給大家。
    2014-11-11
  • node.js中的fs.lchmodSync方法使用說明

    node.js中的fs.lchmodSync方法使用說明

    這篇文章主要介紹了node.js中的fs.lchmodSync方法使用說明,本文介紹了fs.lchmodSync的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node發(fā)出HTTP POST請求的方法實例小結(jié)

    Node發(fā)出HTTP POST請求的方法實例小結(jié)

    這篇文章主要介紹了Node發(fā)出HTTP POST請求的方法,結(jié)合實例形式總結(jié)分析了三種常用的post請求操作方法,以及相關(guān)庫操作注意事項,需要的朋友可以參考下
    2023-05-05
  • node.js中EJS 模板快速入門教程

    node.js中EJS 模板快速入門教程

    本篇文章主要介紹了EJS 模板快速入門學(xué)習(xí),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Nodejs對postgresql基本操作的封裝方法

    Nodejs對postgresql基本操作的封裝方法

    今天小編就為大家分享一篇Nodejs對postgresql基本操作的封裝方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • node.js中的emitter.on方法使用說明

    node.js中的emitter.on方法使用說明

    這篇文章主要介紹了node.js中的emitter.on方法使用說明,本文介紹了emitter.on的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 詳解nodejs微信公眾號開發(fā)——6.自定義菜單

    詳解nodejs微信公眾號開發(fā)——6.自定義菜單

    這篇文章主要介紹了詳解nodejs微信公眾號開發(fā)——6.自定義菜單,自定義菜單能夠幫助公眾號豐富界面,讓用戶更好更快地理解公眾號的功能。
    2017-04-04

最新評論

宜兰市| 色达县| 韩城市| 白河县| 抚松县| 达州市| 蓬溪县| 揭东县| 庐江县| 太和县| 乌拉特后旗| 苍山县| 仙游县| 兰州市| 双柏县| 东乡族自治县| 海门市| 永济市| 石柱| 阳江市| 盖州市| 措美县| 常州市| 苗栗市| 广德县| 沿河| 宝丰县| 高清| 徐闻县| 扎鲁特旗| 万宁市| 枣强县| 宜黄县| 龙陵县| 宝应县| 梅州市| 林芝县| 屏东县| 义乌市| 德兴市| 高州市|