Nodejs建立HTTPS服務器

Nodejs建立HTTPS服務器

從零開始nodejs系列文章,將介紹如何利Javascript作爲服務端腳本,經過Nodejs框架web開發。Nodejs框架是基於V8的引擎,是目前速度最快的Javascript引擎。chrome瀏覽器就基於V8,同時打開20-30個網頁都很流暢。Nodejs標準的web開發框架Express,能夠幫助咱們迅速創建web站點,比起PHP的開發效率更高,並且學習曲線更低。很是適合小型網站,個性化網站,咱們本身的Geek網站!!javascript

關於做者html

  • 張丹(Conan), 程序員Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

轉載請註明出處:
http://blog.fens.me/nodejs-https-server/java

nodejs-https

前言node

互聯網應用愈來愈多,網絡安全問題應該值得你們注意起來,特別是對於有在線支付業務的網站!爲保證用戶的帳戶安全,應該使用HTTPS協議代替HTTP協議,在數據傳輸層保持加密。linux

大部分的美國網站,當涉及到我的信息時,若是不提供HTTPS的服務,多數用戶都會拒絕使用的。中國的網民何時,纔會有這種意識呢?nginx

目錄git

  1. HTTP和HTTPS介紹
  2. 用Nodejs建立HTTPS服務器(Win7)
  3. 用Nodejs建立HTTPS服務器(Linux)
  4. 抓取請求,驗證加密

1. HTTP和HTTPS介紹

HTTP: 超文本傳輸協議 (HTTP-Hypertext transfer protocol) 是一種詳細規定了瀏覽器和萬維網服務器之間互相通訊的規則,經過因特網傳送萬維網文檔的數據傳送協議。程序員

HTTPS:(全稱:Hypertext Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。 它是一個URI scheme(抽象標識符體系),句法類同http:體系。用於安全的HTTP數據傳輸。https:URL代表它使用了HTTP,但HTTPS存在不一樣於HTTP的默認端口及一個加密/身份驗證層(在HTTP與TCP之間)。這個系統的最初研發由網景公司進行,提供了身份驗證與加密通信方法,如今它被普遍用於萬維網上安全敏感的通信,例如交易支付方面。github

HTTPS和HTTP的區別web

  • https協議須要到ca申請證書,通常免費證書不多,須要交費。
  • http是超文本傳輸協議,信息是明文傳輸,https 則是具備安全性的ssl加密傳輸協議。
  • http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。
  • http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

HTTP和HTTPS的介紹,摘自http://baike.baidu.com/view/14121.htm

在Nodejs中,咱們能夠經過內置的https庫,來實現HTTPS服務器。

Nodejs的HTTPS使用文檔:http://nodejs.org/api/https.html

2. 用Nodejs建立HTTPS服務器(Win7)

系統環境

  • win7 64bit
  • IP: 192.168.1.13
  • Nodejs:v0.10.5
  • Npm:1.2.19

建立express的開發環境

~ D:\workspace\javascript>express -e  nodejs-https
~ D:\workspace\javascript>cd nodejs-https && npm install

ejs@0.8.5 node_modules\ejs
express@3.2.6 node_modules\express
├── methods@0.0.1
├── fresh@0.1.0
├── cookie-signature@1.0.1
├── range-parser@0.0.4
├── debug@0.7.4
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── commander@0.6.1
├── mkdirp@0.3.4
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.11 (pause@0.0.1, qs@0.6.5, bytes@0.2.0, cookie@0.0.5, formidable@1.0.14, send@0.1.1)

我本地已經安裝了git客戶端msysgit,其中包括了openssl程序。

~ D:\workspace\javascript\nodejs-https>git --version
git version 1.8.1.msysgit.1

~ D:\workspace\javascript\nodejs-https>openssl version -a
OpenSSL 0.9.8e 23 Feb 2007
built on: Sat Sep 15 20:34:58 EDT 2007
platform: MSys
options:  bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) blowfish(idx)
compiler: gcc -D_WINDLL -DOPENSSL_PIC -DOPENSSL_THREADS  -DDSO_DLFCN -DHAVE_DLFCN_H -DTERMIOS -DL_ENDIAN -D__CYGWIN__ -f
omit-frame-pointer -fnative-struct -O3 -mcpu=pentium -march=i486 -Wall -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2 -
DSHA1_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM
OPENSSLDIR: "/usr/ssl"

openssl生成證書文件

#生成私鑰key文件:
~ D:\workspace\javascript\nodejs-https>openssl genrsa -out privatekey.pem 1024
Generating RSA private key, 1024 bit long modulus
...........................++++++
........++++++
e is 65537 (0x10001)

#經過私鑰生成CSR證書籤名
~ D:\workspace\javascript\nodejs-https>openssl req -new -key privatekey.pem -out certrequest.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:fens.me
Organizational Unit Name (eg, section) []:fens.me
Common Name (eg, YOUR name) []:Conan Zhang
Email Address []:bsspirit@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# 經過私鑰和證書籤名生成證書文件
~ D:\workspace\javascript\nodejs-https>openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
Signature ok
subject=/C=CN/ST=Beijing/L=Beijing/O=fens.me/OU=fens.me/CN=Conan Zhang/emailAddress=bsspirit@gmail.com
Getting Private key

新生成了3個文件:certificate.pem, certrequest.csr, privatekey.pem

~ D:\workspace\javascript\nodejs-https>ls -l
total 17
-rwx------  1 4294967295 mkpasswd 877 Dec 14 10:53 app.js
-rwx------  1 4294967295 mkpasswd 956 Dec 14 11:22 certificate.pem
-rwx------  1 4294967295 mkpasswd 704 Dec 14 11:21 certrequest.csr
drwx------+ 1 4294967295 mkpasswd   0 Dec 14 11:10 node_modules
-rwx------  1 4294967295 mkpasswd 216 Dec 14 11:03 package.json
-rwx------  1 4294967295 mkpasswd 887 Dec 14 11:20 privatekey.pem
drwx------+ 1 4294967295 mkpasswd   0 Dec 14 10:53 public
drwx------+ 1 4294967295 mkpasswd   0 Dec 14 10:53 routes
drwx------+ 1 4294967295 mkpasswd   0 Dec 14 10:53 views
  • privatekey.pem: 私鑰
  • certrequest.csr: CSR證書籤名
  • certificate.pem: 證書文件

修改啓動文件:app.js

~ vi app.js

//最下面
var https = require('https')
    ,fs = require("fs");

var options = {
    key: fs.readFileSync('./privatekey.pem'),
    cert: fs.readFileSync('./certificate.pem')
};

https.createServer(options, app).listen(3011, function () {
    console.log('Https server listening on port ' + 3011);
});

啓動服務器:

~ D:\workspace\javascript\nodejs-https>node app.js

Express server listening on port 3000
Https server listening on port 3011

打開瀏覽器:HTTP訪問
https-http

HTTPS訪問
https-https

查看證書
https-https-cert

因爲咱們證書是本身建立的,沒有通過第三方機構的驗證,所以會出現警告的提示。你們能夠去有資質的網絡運營商,去申請本身的證書。好比:godaddy SSL Certificates,優惠碼:WOWfensme

這樣咱們就在win7完整的HTTPS服務器建立。

3. 用Nodejs建立HTTPS服務器(Linux)

建立過程與win7相似

系統環境

  • Linux: Ubuntu 12.04.2 LTS 64bit deskop
  • IP: 192.168.1.20
  • Nodejs: npm 1.2.21
  • node v0.11.2

建立express項目

~ cd /home/conan/nodejs
~ express -e  nodejs-https
~ cd nodejs-https
~ sudo npm install

用openssl生成證書文件

~ openssl version -a
OpenSSL 1.0.1 14 Mar 2012
built on: Tue Jun  4 07:26:06 UTC 2013
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_NO_TLS1_2_CLIENT -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"

~ openssl genrsa -out privatekey.pem 1024
~ openssl req -new -key privatekey.pem -out certrequest.csr 
~ openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem

修改文件app.js

~ vi app.js

//在最下面
var https = require('https')
    ,fs = require("fs");

var options = {
    key: fs.readFileSync('./privatekey.pem'),
    cert: fs.readFileSync('./certificate.pem')
};

https.createServer(options, app).listen(3011, function () {
    console.log('Https server listening on port ' + 3011);
});

啓動服務器

~ node app.js

Express server listening on port 3000
Https server listening on port 3011

打開瀏覽器:
https-https-linux

4. 抓取請求,驗證加密

爲了驗證數據在傳輸過程當中是加密的,咱們用wireshark抓取網絡包。

HTTP請求:http://192.168.1.20:3000/users?a=111
http-request

HTTPS請求:https://192.168.1.20:3011/users?a=112
https-request

在HTTP下面,URL請求的參數是被暴露的。在HTTPS下面,URL的請求參數是被加密的。所以,但願須要填寫我的信息,及在線支付的網站,都把HTTPS服務器搭建起來。防止私密數據,在網絡傳輸過程當中被獲取。

轉載請註明出處:
http://blog.fens.me/nodejs-https-server/

打賞做者

 

This entry was posted in Javascript語言實踐網絡技術

贊助商廣告(購買)

  • Pingback: Nodejs學習路線圖 | 粉絲日誌()

  • mark

  • Min

    mark!

  • wretchy

    mark

  • lenchs

    mark

  • HelloQiu

    你好,我有一個使用express建立的https,但不知道老是不明的不能訪問,進程和端口都正常,就是網頁打不開,如下爲代碼:
    var app = express();
    app.get(‘/a’, function(req, res) {….});
    app.get(‘/b’, function(req, res) {….});
    var credentials = {
    key: fs.readFileSync(‘k.key’, ‘utf8’),
    cert: fs.readFileSync(‘c.crt’, ‘utf8’),
    passphrase: ‘****************’
    }
    https.createServer(credentials, app).listen(1234);

  • fuchao2012

    working with the crawls in https. helps alot.

  • skytouchzyt

    爲何我在本地建立https能夠訪問,上傳到服務器建立,就提示ssl鏈接錯誤?

  • 葉忠

    您好,我在github上下了一個SkyRTC的demo,https://github.com/LingyuCoder/SkyRTC-demo
    準備加ssl的時候怎麼都不行,我已經試了好多版本的方法了,看了很多YouTube的視頻,仍是不行,請問您能夠你幫幫我嗎?
    這個是demo的代碼

    var express = require(‘express’);
    var app = express();
    var server = require(‘http’).createServer(app);
    var SkyRTC = require(‘skyrtc’).listen(server);
    var path = require(「path」);
    var port = process.env.PORT || 3000;
    server.listen(port);

    下面的是我測試的

    /*

    var express = require(‘express’);

    var app = express();

    const https = require(‘https’);//.createServer(app);

    const fs = require(‘fs’);

    var path = require(「path」);

    var options = {

    key: fs.readFileSync(‘./privatekey.pem’),

    cert: fs.readFileSync(‘.server.pem’)

    };

    const server = https.createServer(options, app);

    var SkyRTC = require(‘skyrtc’).listen(server);

    var port = process.env.PORT || 80;

    server.listen(port);

    */

    /*

    var express = require(‘express’);

    var app = express();

    var path = require(「path」);

    const fs = require(‘fs’);

    var options = {

    key: fs.readFileSync(‘./privatekey.pem’),

    cert: fs.readFileSync(‘.server.pem’)

    };

    var server = require(‘https’).createServer(options, app);

    var SkyRTC = require(‘skyrtc’).listen(server);

    var port = process.env.PORT || 80;

    server.listen(port);

    */

    /*44444

    var express = require(‘express’);

    var path = require(「path」);

    const https = require(‘https’)

    ,fs = require(‘fs’);

    const options = {

    key: fs.readFileSync(‘./privatekey.pem’),

    cert: fs.readFileSync(‘.server.pem’)

    };

    const server = https.createServer(options,(req, res) => {

    res.sendfile(__dirname + ‘/index.html’);

    }).listen(80);

    var app = express();

    server.on(‘request’,app);

    server.listen(80)

    var SkyRTC = require(‘skyrtc’).listen(server);

    */

    加了ssl以後所有都是網頁打不開,沒有任何報錯。
    麻煩您抽空幫我看看,謝謝

    • 抱歉我不熟悉SkyRTC 。
      若是你這種配置有問題,你也能夠嘗試在前前架個nginx處理https請求,nginx和node用http鏈接。

      • 葉忠

        我這邊已經解決了,不過很是感謝您能抽出時間來回復。謝謝!

相關文章
相關標籤/搜索