简介网络安全
数据在服务器端和客户端之间传递是明文传递,一旦网络被人监控,数据就可能被截获。并且内容一目了然。这个时候我们想要说对传输的数据进行加密。网景公司提出了对数据的加密,SSL作为一种安全协议,他在传输层提供对网络连接加密和解密,对应用层而言是透明的,因为在此之前已经完成了对数据进行加密解密的过程。
node在网络安全上提供了3个模块,分别是crypto、tls、https。
- crypto:主要是提供加密算法的,比如 SHA1、MD5等。
- tls:是类似于 net 模块的功能,但是在建立 TCP 连接时对连接进行了 TLS/SSL 加密。
- https:也是与 http 类似,也进行了加密。
TLS/SSL
密钥
这是一个公钥/私钥非对称的结构。每个服务器端和客户端都有自己的公司钥,公钥用来加密要传输的数据,私钥用来解密接收到的数据。公钥私钥要配对使用。 在建立安全传输之前,客户端和服务器端之间需要互换公钥。客户端发送数据时要通过服务器端的公钥进行加密,服务器端发送数据时则需要客户端的公钥进行加密。
缺点在于,如果中间人攻击伪造自己的身份还是可以破解这种单纯的密钥加密的。在客户端扮演服务端的角色,在服务器端扮演客户端的角色,就可以获取双方的信任。拿到双方的公钥和私钥了。
数字证书。
为了防止上面的情况发生,引入了第三方的:CA(数字认证中心),CA的作用是为站点颁发证书。机构认证非常耗时,所以一般都采用自己扮演CA机构,给自己的服务器颁发签名证书。
# 生成服务器私钥
# 扮演证书机构证书
openssl genrsa -out ca.key 1024
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
# 私钥
openssl genrsa -out server.key 1024
# 获得证书
openssl req -new -key server.key -out server.csr
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
// 将所有的证书和 key 放到 key 文件下
var tls = require('tls'),
fs = require('fs');
var options = {
key: fs.readFileSync('./key/server.key'),
cert: fs.readFileSync('./key/server.crt'),
requestCert: true,
ca: [fs.readFileSync('./key/ca.crt')]
}
var server = tls.createServer(options, function(stream){
console.log('server connected', stream.authorized ? 'authorized' : 'unauthorized');
stream.write('welcome!');
stream.setEncoding('utf8');
stream.pipe(stream);
});
server.listen(3333, function(){
console.log('server bound');
})
# 客户端私钥生成
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt
// 客户端代码
var tls = require('tls'),
fs = require('fs');
var options = {
key: fs.readFileSync('./key/client.key'),
cert: fs.readFileSync('./key/client.crt'),
ca: [fs.readFileSync('./key/ca.crt')]
}
var stream = tls.connect(3333, options, function(){
console.log('client connected', stream.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(stream);
})
stream.setEncoding('utf8');
stream.on('data', function(data){
console.log(data);
})
stream.on('end', function(){
server.close();
})
HTTPS
HTTPS是建立在安全连接下的HTTP,HTTPS服务需要用到私钥和签名证书。服务证书从上面就已经获取了。
// 服务器端
var https = require('https'),
fs = require('fs');
var options = {
key: fs.readFileSync('./key/server.key'),
cert: fs.readFileSync('./key/server.crt')
}
https.createServer(options, function(req, res){
res.writeHead(200);
res.end('hello world')
}).listen(3333, function(){
console.log('server bound');
})
// 客户端代码
var https = require('https'),
fs = require('fs');
var options = {
hostname: 'localhost',
port: 3333,
path: '/',
method: 'GET',
key: fs.readFileSync('./key/client.key'),
cert: fs.readFileSync('./key/client.crt'),
ca: [fs.readFileSync('./key/ca.crt')]
}
options.agent = new https.Agent(options);
var req = https.request(options, function(res){
res.setEncoding('utf8');
res.on('data', function(d){
console.log(d);
})
})
req.end();
req.on('error', function(e){
console.log(e)
})