最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • https是如何做到安全加密的?

    正文概述 掘金(hpstream_)   2021-04-22   699

    由于 HTTP 天生“明文”的特点,整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求 / 响应报文,数据不具有可信性。因此产生了如下问题:

    1. 信息被窃听
    2. 信息被篡改
    3. 信息被劫持

    什么是https

    HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法

    • 散列函数 散列函数验证信息的完整性
    • 对称加密 对称加密算法采用协商的密钥对数据加密
    • 非对称加密 非对称加密实现身份认证和密钥协商

    https是如何做到安全加密的?

    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; 这样子就篡改了你消息的本意;
    

    数字签名

    用数字签名可以防止,信息被篡改。(数字签名使用的是摘要算法)

    我们用浏览器的私钥,进行信息摘要,做成签名,和信息一起发送给服务端;服务端进行验签,发现是本人,才继续执行逻辑;这样子就可以防止信息被篡改了。 https是如何做到安全加密的?

    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');
    }
    

    钓鱼网站

    通过上面的方式,黑客无法做好窃听和篡改了,但是可以做到截取,自己假装一个服务器(俗称钓鱼网站);听过这种方式来欺骗用户;那么怎么防止呢?

    https是如何做到安全加密的?

    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如果保证我们安全做的事情。


    起源地下载网 » https是如何做到安全加密的?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元