CIA三属性:完整性(Confidentiality)、保密性(Integrity)、可用性(Availability),也称信息安全三要素。
核心技术:用非对称加密传输对称加密的密钥,然后用对称密钥进行通信
HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),超文本传输协议。
HTTPS 解决数据传输安全问题的方案就是使用加密算法,具体来说是混合加密算法,也就是对称加密和非对称加密的混合使用。
对称加密,顾名思义就是加密和解密都是使用同一个密钥,常见的对称加密算法有 DES、3DES 和 AES 等,其优缺点如下:
非对称加密,顾名思义,就是加密和解密需要使用两个不同的密钥:公钥(public key)和私钥(private key)。
公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。
过程详解:甲方生成一对密钥并将其中的一把作为公钥对外公开;得到该公钥的乙方使用公钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的私钥对加密后的信息进行解密。
优缺点如下:
常用非对称加密算法:RSA算法
HTTPS 并非独立的通信协议,而是对 HTTP 的扩展,保证了通信安全,二者关系如下:
SSL/TLS如何解决HTTP的风险:
公钥加密,私钥加密 --> 加密;
私钥加密,公钥解密 --> 签名。
每一个「框」都是一个记录(record),记录是 TLS 收发数据的基本单位
实现RSA密钥交换
客户端首先会发一个「Client Hello」消息,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,支持的压缩算法,以及生成的随机数
服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否支持,和从密码套件列表中选择一个密码套件,还有选择压缩算法(安全性原因,一般不压缩),以及生成随机数(Server Random)。
接着,返回「Server Hello」消息,消息里面有服务器确认的 TLS 版本号,也给出了随机数(Server Random),然后从客户端的密码套件列表选择了一个合适的密码套件。
服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书。
随后服务端发了「Server Hello Done」消息,目的是告诉客户端,打招呼完毕
数字证书包含:
数字证书签发和验证流程
客户端验证完证书后,认为可信则继续往下走。接着,客户端就会生成一个新的随机数 (pre-master),用服务器的 RSA 公钥加密该随机数,通过「Change Cipher Key Exchange」消息传给服务端。
服务端收到后,用 RSA 私钥解密,得到客户端发来的随机数 (pre-master)。
至此,客户端和服务端双方都共享了三个随机数,分别是 Client Random、Server Random、pre-master。
双方根据已经得到的三个随机数,生成会话密钥(Master Secret),它是对称密钥,用于对后续的 HTTP 请求/响应的数据加解密。
生成完会话密钥后,然后客户端发一个「Change Cipher Spec」,告诉服务端开始使用加密方式发送消息
客户端再发一个「Encrypted Handshake Message(Finishd)」消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密,让服务器做个验证,验证加密通信是否可用和之前握手信息是否有被中途篡改过。
服务端向客户端发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。
数组(array)是按次序排列的一组值。每个值的位置都有编号(从0开始),整个数组用方括号表示。
var arr = ['a', 'b', 'c'];
位置分别为0,1,2
也可先定义后赋值
var arr = [];
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
任何类型的数据,都可以放入数组。
var arr = [
{a: 1},
[1, 2, 3],
function() {return true;}
];
arr[0] // Object {a: 1} --- 对象
arr[1] // [1, 2, 3] --- 数组
arr[2] // function (){return true;} --- 函数
数组内元素是数组,那便是多维数组
var a = [[1, 2], [3, 4]];
a[0][1] // 2
a[1][1] // 4
数组是一种特殊的对象。typeof 运算符认为数组的类型就是对象
typeof [1, 2, 3] // "object"
数组的键名是有序的
var arr = ['a', 'b', 'c'];
Object.keys(arr)
// ["0", "1", "2"]
`Object.keys`方法返回数组的所有键名。
数组的键名其实也是字符串,非字符串的键名会被转为字符串
var arr = ['a', 'b', 'c'];
arr['0'] // 'a'
arr[0] // 'a'
一个值总是先转成字符串,再作为键名进行赋值。
var a = [];
a[1.00] = 6;
a[1] // 6
对象的两种读取成员的方法:点结构(object.key)和方括号结构(object.[key])
数组的length
属性,返回数组的成员数量。length 是一个动态的值,键明中的最大整数加1
['a', 'b', 'c'].length // 3
var arr = ['a', 'b'];
arr.length // 2
arr[2] = 'c';
arr.length // 3
arr[9] = 'd';
arr.length // 10
arr[1000] = 'e';
arr.length // 1001
数组的数字键不需要连续,`length`属性的值总是比最大的那个整数键大`1`,中间的位置都是空位(undefined)
length属性可写,若设置小于当前成员个数的值,那便会自动减少。(后进先出)
var arr = [ 'a', 'b', 'c' ];
arr.length // 3
arr.length = 2;
arr // ["a", "b"]
---- 清空
arr.length = 0;
arr // []
当`length`属性设为大于数组个数时,读取新增的位置都会返回`undefined`
var a = ['a'];
a.length = 3;
a[1] // undefined
数组本质上是一种对象,所以可以为数组添加属性,但是这不影响length
属性的值。
var a = [];
a['p'] = 'abc';
a.length // 0
a[2.1] = 'abc';
a.length // 0
a[0] = 'cao';
a.length // 1
检查某个键名是否存在的运算符in
,适用于对象,也适用于数组。
var arr = [ 'a', 'b', 'c' ];
2 in arr // true
'2' in arr // true
4 in arr // false
数组的某个位置为空位,in运算符返回flase
var arr = [];
arr[100] = 'a';
100 in arr // true
1 in arr // false
for...in
循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象。
var a = [1,2,3];
for(var key in a){
console.log(a[key]);
}
// 1
// 2
// 3
for (var key in a) {
console.log(key);
}
// 0
// 1
// 2
数组的遍历可以考虑使用`for`循环或`while`循环。
var a = [1, 2, 3];
// for循环
for(var i = 0; i < a.length; i++) {
console.log(a[i]);
}
// while循环
var i = 0;
while (i < a.length) {
console.log(a[i]);
i++;
}
var l = a.length;
while (l--) {
console.log(a[l]);
}
数组的forEach
方法,也可以用来遍历数组
var colors = ['red', 'green', 'blue'];
colors.forEach(function (color) {
console.log(color);
});
// red
// green
// blue