https简介
http传输是明文数据,通常端口80或者8080,https是SSL安全加密后的密文数据,通常端口443 (www.ayjs.net杨洋 )
在实际场景中,私钥和公钥都保存在服务端,在服务器与客户端相互确定彼此身份之前,公钥会传送到客户端,客户端随机发送消息给服务器端,服务器端拿到收到的字符计算成Hash值后用私钥加密再发送给客户端;客户端收到数据后用之前收到的公钥解密,解密后,把之前随机发出的消息也计算成hash值,检查是否一致;如果一致,那么握手成功,客户端选择一个加密算法和相应秘匙并用公钥加密后,发送服务器端;服务器端接收到加密算法和密匙后,也就可以正式沟通数据了
创建HTTPS服务器
openssl环境
手工编译太难了,我表示失败了3个小时,最终放弃。
下载我上传的windows编译后的: 百度云
我拷贝到了c盘,并改了名字为openssl
如果使用openssl.exe使用方法,就只能
C:\openssl\bin\openssl.exe 其他命令
创建私钥
windows版本: C:\openssl\bin\openssl.exe genrsa -out c://privatekey.pem 1024非windows的终端应该自带openssl命令了
openssl genrsa -out c://privatekey.pem 1024
那么下面的我就直接用windows的来讲了。
创建证书签名请求
C:\openssl\bin\openssl.exe req -new -key c://privatekey.pem -out c://client.csr
然后输入信息,生成证书
获取证书
证书应该是一个经过证书授证中心签名的文件,该证书文件内包含了服务器端提供的公钥以及证书的办法机构等信息
C:\openssl\bin\openssl.exe x509 -req -in c://client.csr -signkey c://privatekey.pem -out c://certificate.pem
创建pfx文件
C:\openssl\bin\openssl.exe pkcs12 -export -in c://certificate.pem -inkey c://privatekey.pem -out c://certificate.pfx
在这些文件,pfx文件为可选用文件,文件都有了后,可以使用https模块中的createServer方法创建一个https服务器
我两次密码都是123456
新建httpsDemo.js
/** * Created by aaronyang on 2015/10/30. */ var https=require(‘https‘); var fs=require(‘fs‘); var privatekey=fs.readFileSync(‘c:/privatekey.pem‘); var pc=fs.readFileSync(‘c:/certificate.pem‘); var options={ key:privatekey, cert:pc } var server=https.createServer(options, function (req,res) { console.log(req.url); if(req.url!==‘favicon.ico‘){ res.setHeader(‘Content-Type‘,‘text/html‘); res.write(‘<html><head><meta charset="utf-8"/> </head>‘); res.write(‘hello ay!https服务‘); res.end(); } }) server.listen(1443,‘localhost‘, function () { console.log(‘服务器开始监听‘); })
效果图:这里注意1024以下的端口,需要管理员权限才能监听
这里的createServer方法相对于http多了个options参数,这个参数值太多了,我稍微列举几个
pfx指定pfx文件读取出来的公钥以及证书。使用该属性值后,不需要指定key、cert以及ca属性值
passphrase用于为私钥文件或pfx文件指定密码。
* key指定从后缀名为pem的私钥文件中读取出来的私钥。
cert:用于指定从后缀名为pem的文件中读取出来的公钥。必须指定,除非制定了pfx值
ca:为一个字符串数组或一个buffer对象数组,用于指定一组证书,默认属性值为几个注明的证书授证中心,例如VerlSign
ciphers:属性值为一个字符串,用于描述需要使用或取消使用的密码。为了阻止BEAST攻击,推荐将ciphers属性与honorCipherOrder属性结合使用,以指定非CBC(Cipher-block chaining密码分组链接)模式的密码的优先级,默认属性值为AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
requestCert:布尔值,默认false,为true的时候,服务器在确认链接时要求客户端提供证书。
还有handshakeTimeout,rejectUnauthorized,NPNProtocols,sessionIdContext
跟HTTP一样,当然了也有close方法,error方法,这里不列举了,具体可以参考http的
HTTPS客户端
在https模块中,可以使用request方法向其他使用HTTPS协议的网站请求数据。
https.request(options,callback)
其中options参数,跟createServer的参数是一样的。
跟http的request差不过,都只不过多了个options参数
这里讲下options中的agent参数,用于指定用户代理。在Nodejs中,使用https.Agent类代表一个用户代理。在nodejs中,用户代理默认在请求数据时使用keep-alive连接,同时使用一个全局的https.Agent对象。可以为agent属性值显式指定一个https.Agent对象,也可以通过将agent属性值指定为false的方法从连接池中自动挑选一个当前连接状态为关闭的https.Agent对下网
例如.
var opt1={ hostname:‘npmjs.org‘, port:443, path:‘/‘, method:‘GET‘, agent:false } var req=https.request(opt1, function (res) { console.log(‘状态码:‘ + res.statusCode); console.log(‘响应头:‘ + JSON.stringify(res.headers)); res.setEncoding(‘utf8‘); res.on(‘data‘, function (data) { console.log(‘data:‘+data); }) })
当然也有https.get方法
在建立连接的过程中,当为连接分配端口时候,触发https.ClientRequest对象的socket事件。
下面是客户端发送请求,1秒后服务器没反应,客户就断开请求abort
req.on(‘socket‘, function (socket) { socket.setTimeout(1000); socket.on(‘timeout‘, function () { req.abort(); }); })
req.on(‘error‘,function(err){})
具体的用法可以参考HTTP去编写。