由于 HTTP 天生“明文”的特点,整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求 / 响应报文,数据不具有可信性。因此产生了如下问题:
- 信息被窃听
- 信息被篡改
- 信息被劫持
什么是https
HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法
- 散列函数 散列函数验证信息的完整性
- 对称加密 对称加密算法采用协商的密钥对数据加密
- 非对称加密 非对称加密实现身份认证和密钥协商
SSL/TLS的关系
SSL 即安全套接层(Secure Sockets Layer),在 OSI 模型中处于第 5 层(会话层),由网景公司于 1994 年发明,有 v2 和 v3 两个版本,而 v1 因为有严重的缺陷从未公开过。 SSL 发展到 v3 时已经证明了它自身是一个非常好的安全通信协议,于是互联网工程组 IETF 在 1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSLv3.1。
了解了基础概念,我们一起来看看https是如何解决上述问题的。
加密信息
我们知道http 是明文传输的,那我们很容易想到给明文加密呗,把传输的内容进行加密,服务端进行解密。这样子别人就不知道里面的内容是什么了。
const crypto = require('crypto');
function encrypt(data, key, iv) {
let decipher = crypto.createCipheriv('aes-128-cbc', key, iv);
decipher.update(data);
return decipher.final('hex');
}
function decrypt(data, key, iv) {
let decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
decipher.update(data, 'hex');
return decipher.final('utf8');
}
let key = '1234567890123456';
let iv = '1234567890123456';
let data = "hello";
let encrypted = encrypt(data, key, iv);
console.log("数据加密后:", encrypted);
let decrypted = decrypt(encrypted, key, iv);
console.log("数据解密后:", decrypted);
** 但是服务器和客户端怎么公用一个秘钥呢?在互联网上没有办法安全的交换密钥。**
使用非对称加密,加密秘钥
let {
generateKeyPairSync,
privateEncrypt,
publicDecrypt
} = require('crypto');
let rsa = generateKeyPairSync('rsa', {
modulusLength: 1024,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: 'server_passphrase'
}
});
let message = 'hello';
console.log(rsa)
let enc_by_prv = privateEncrypt({
key: rsa.privateKey,
passphrase: 'server_passphrase'
}, Buffer.from(message, 'utf8'));
console.log('encrypted by private key: ' + enc_by_prv.toString('hex'));
let dec_by_pub = publicDecrypt(rsa.publicKey, enc_by_prv);
console.log('decrypted by public key: ' + dec_by_pub.toString('utf8'));
现在虽然可以做到数据防止被窃听,但是还是非常有可能被篡改的;
比如说:
浏览器 发送 我爱你 加密后 waai;
浏览器 发送 我不爱你 加密后 wbai;
黑客拦截到数据,经过观察和分析,发现了规律。
当浏览器发送 我爱你 给服务器试,直接讲密文篡改成 wbai; 这样子就篡改了你消息的本意;
数字签名
用数字签名可以防止,信息被篡改。(数字签名使用的是摘要算法)
我们用浏览器的私钥,进行信息摘要,做成签名,和信息一起发送给服务端;服务端进行验签,发现是本人,才继续执行逻辑;这样子就可以防止信息被篡改了。
let { generateKeyPairSync, createSign, createVerify } = require('crypto');
let passphrase = 'zhufeng';
let rsa = generateKeyPairSync('rsa', {
modulusLength: 1024,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase
}
});
let content = 'hello';
const sign = getSign(content, rsa.privateKey, passphrase);
let serverCertIsValid = verifySign(content, sign, rsa.publicKey);
console.log('serverCertIsValid', serverCertIsValid);
function getSign(content, privateKey, passphrase) {
var sign = createSign('RSA-SHA256');
sign.update(content);
return sign.sign({ key: privateKey, format: 'pem', passphrase }, 'hex');
}
function verifySign(content, sign, publicKey) {
var verify = createVerify('RSA-SHA256');
verify.update(content);
return verify.verify(publicKey, sign, 'hex');
}
钓鱼网站
通过上面的方式,黑客无法做好窃听和篡改了,但是可以做到截取,自己假装一个服务器(俗称钓鱼网站);听过这种方式来欺骗用户;那么怎么防止呢?
let { generateKeyPairSync, createSign, createVerify, createHash } = require('crypto');
let passphrase = 'zhufeng';
let rsa = generateKeyPairSync('rsa', {
modulusLength: 1024,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase
}
});
const info = {
domain: "http://127.0.0.1:8080",
publicKey: rsa.publicKey
};
const hash = createHash('sha256').update(JSON.stringify(info)).digest('hex');
const sign = getSign(hash, rsa.privateKey, passphrase);
const cert = { info, sign };
let certIsValid = verifySign(hash, cert.sign, rsa.publicKey);
console.log('certIsValid', certIsValid);
function getSign(content, privateKey, passphrase) {
var sign = createSign('RSA-SHA256');
sign.update(content);
return sign.sign({ key: privateKey, format: 'pem', passphrase }, 'hex');
}
function verifySign(content, sign, publicKey) {
var verify = createVerify('RSA-SHA256');
verify.update(content);
return verify.verify(publicKey, sign, 'hex');
}
通过如上流程,可以成功避免坏人的信息劫持。
结论:
上述就是https如果保证我们安全做的事情。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!