HTTP和HTTPS有什么不同(如何利用http2的二进制的传输通道做请求加密延签)

304 阅读8分钟

HTTP和HTTPS是什么?

我们使用浏览器访问一个网站页面,在浏览器的地址栏中我们会看到一串URL

网站的URL会分为两部分:通信协议和域名地址。

域名地址都很好理解,不同的域名地址表示网站中不同的页面,而通信协议,简单来说就是浏览器和服务器之间沟通的语言。网站中的通信协议一般就是HTTP协议和HTTPS协议。

HTTP协议

HTTP协议是一种使用明文数据传输的网络协议。一直以来HTTP协议都是最主流的网页协议,但是互联网发展到今天,HTTP协议的明文传输会让用户存在一个非常大的安全隐患。试想一下,假如你在一个HTTP协议的网站上面购物,你需要在页面上输入你的银行卡号和密码,然后你把数据提交到服务器实现购买。假如这个适合,你的传输数据被第三者给截获了,由于HTTP明文数据传输的原因,你的银行卡号和密码,将会被这个截获人所得到。现在你还敢在一个HTTP的网站上面购物吗?你还会在一个HTTP的网站上面留下你的个人信息吗?

HTTPS协议

HTTPS协议可以理解为HTTP协议的升级,就是在HTTP的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息让然是安全的。这就是HTTP和HTTPS的最大区别。

其实如果你足够细心,你会发现现在很多大型互联网网站,如百度、淘宝、腾讯很早就已经把HTTP换成HTTPS了。

HTTP和HTTPS的其他不同

数据加密传输,是HTTP和HTTPS之间的本质性区别,其实除了这个之外,HTTPS网站和HTTP网站还有其他地方不同。

当你使用Chrome浏览器访问一个HTTP网站的时候,你会发现浏览器会对该HTTP网站显示“不安全”的安全警告,提示用户当前所访问的网站可能会存在风险。

而假如你访问的是一个HTTPS网站时,情况却是完全不一样。你会发现浏览器的地址栏会变成绿色,企业名称会展示在地址栏中,地址栏上面还会出现一把“安全锁”的图标。这些都会给与用户很大的视觉上的安全体验。以下是EV证书在不同浏览器中的展现。

除了浏览器视觉上不同以外,HTTPS网站和HTTP网站还有一个很重要的区别,就是对搜索排名的提升,这也是很多站长所关注的地方。

百度和谷歌两大搜索引擎都已经明确表示,HTTPS网站将会作为搜索排名的一个重要权重指标。也就是说HTTPS网站比起HTTP网站在搜索排名中更有优势。

HTTPS网站相比起HTTP网站拥有着多种的优势,HTTP明显已经不能适应当今这个互联网时代,可以预见到HTTP在不久的将来将会全面被HTTPS所取代。

HTTPS是如何对数据进行加密的

HTTPS是如何对数据进行加密的?对安全或密码学基础有了解的同学,应该知道常见的加密手段。一般来说,加密分为对称加密、非对称加密(也叫公开密钥加密)。

对称加密对的意思就是,加密数据用的密钥,跟解密数据用的密钥是一样的。

对称加密的优点在于加密、解密效率通常比较高。缺点在于,数据发送方、数据接收方需要协商、共享同一把密钥,并确保密钥不泄露给其他人。此外,对于多个有数据交换需求的个体,两两之间需要分配并维护一把密钥,这个带来的成本基本是不可接受的。

非对称加密非对称加密的意思就是,加密数据用的密钥(公钥),跟解密数据用的密钥(私钥)是不一样的。

什么叫做公钥呢?其实就是字面上的意思——公开的密钥,谁都可以查到。因此非对称加密也叫做公开密钥加密。

相对应的,私钥就是非公开的密钥,一般是由网站的管理员持有。

公钥、私钥两个有什么联系呢? 简单的说就是,通过公钥加密的数据,只能通过私钥解开。通过私钥加密的数据,只能通过公钥解开。

很多同学都知道用私钥能解开公钥加密的数据,但忽略了一点,私钥加密的数据,同样可以用公钥解密出来。而这点对于理解HTTPS的整套加密、授权体系非常关键。

举个非对称加密的例子

登陆用户:小明

授权网站:某知名社交网站(以下简称XX)

小明都是某知名社交网站XX的用户,XX出于安全考虑在登陆的地方用了非对称加密。小明在登陆界面敲入账号、密码,点击“登陆”。于是,浏览器利用公钥对小明的账号密码进行了加密,并向XX发送登陆请求。XX的登陆授权程序通过私钥,将账号、密码解密,并验证通过。之后,将小明的个人信息(含隐私),通过私钥加密后,传输回浏览器。浏览器通过公钥解密数据,并展示给小明。

步骤一: 小明输入账号密码 --> 浏览器用公钥加密 --> 请求发送给XX

步骤二: XX用私钥解密,验证通过 --> 获取小明社交数据,用私钥加密 --> 浏览器用公钥解密数据,并展示。

用非对称加密,就能解决数据传输安全的问题了吗?前面特意强调了一下,私钥加密的数据,公钥是可以解开的,而公钥又是加密的。也就是说,非对称加密只能保证单向数据传输的安全性。

请求二次加密延签

利用HTTP2的二进制传输通道进行请求加密和延签(延迟签名),可以提高数据传输的安全性和完整性

什么是请求加密和延签

  • 请求加密:在发送请求之前对请求数据进行加密,以确保在传输过程中数据不被窃取或篡改。
  • 延签(延迟签名) :在请求数据被处理之前,对数据进行签名。延签通常用于确保数据完整性和验证数据来源。

利用HTTP/2进行加密和延签的步骤

  1. 设置SSL/TLS

    • HTTP/2本身是在SSL/TLS之上的,这意味着所有HTTP/2通信默认是加密的。这提供了基础的传输层加密,确保数据在传输过程中不被窃取或篡改。
  2. 请求数据加密

    • 在应用层对数据进行加密。在发送请求之前,使用对称或非对称加密算法对请求数据进行加密。
    • 对称加密(例如AES):客户端和服务器共享一个密钥,使用该密钥加密和解密数据。
    • 非对称加密(例如RSA):客户端使用服务器的公钥加密数据,服务器使用私钥解密数据。
  3. 延签

    • 数字签名:在发送请求之前,使用客户端的私钥对请求数据进行签名。签名可以验证数据的完整性和来源。
    • 生成签名后,将签名和加密后的数据一起发送到服务器。
  4. 服务器端处理

    • 解密数据:服务器使用相应的密钥解密请求数据。
    • 验证签名:服务器使用客户端的公钥验证请求数据的签名,以确保数据未被篡改且确实来源于客户端。

示例代码

以下是使用JavaScript进行数据加密和签名的示例。假设我们使用AES进行对称加密,RSA进行签名:

客户端加密和签名

// 使用CryptoJS进行加密
const CryptoJS = require('crypto-js');
const NodeRSA = require('node-rsa');

// 对称加密(AES)
function encryptData(data, secretKey) {
    return CryptoJS.AES.encrypt(data, secretKey).toString();
}

// 非对称签名(RSA)
function signData(data, privateKey) {
    const key = new NodeRSA(privateKey);
    return key.sign(data, 'base64');
}

// 示例请求数据
const requestData = JSON.stringify({ message: "Hello, HTTP/2!" });
const secretKey = "mySecretKey12345";  // 对称密钥
const privateKey = "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----";  // RSA私钥

// 加密请求数据
const encryptedData = encryptData(requestData, secretKey);

// 生成数据签名
const signature = signData(encryptedData, privateKey);

// 发送加密数据和签名
const http2 = require('http2');
const client = http2.connect('https://example.com');
const req = client.request({
    ':path': '/',
    'encrypted-data': encryptedData,
    'signature': signature
});

req.end();

服务器端解密和验证

const CryptoJS = require('crypto-js');
const NodeRSA = require('node-rsa');
const http2 = require('http2');

// 对称解密(AES)
function decryptData(encryptedData, secretKey) {
    const bytes = CryptoJS.AES.decrypt(encryptedData, secretKey);
    return bytes.toString(CryptoJS.enc.Utf8);
}

// 非对称验证签名(RSA)
function verifySignature(data, signature, publicKey) {
    const key = new NodeRSA(publicKey);
    return key.verify(data, signature, 'utf8', 'base64');
}

const secretKey = "mySecretKey12345";  // 对称密钥
const publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----";  // RSA公钥

const server = http2.createServer((req, res) => {
    const encryptedData = req.headers['encrypted-data'];
    const signature = req.headers['signature'];

    // 验证签名
    if (verifySignature(encryptedData, signature, publicKey)) {
        // 解密数据
        const decryptedData = decryptData(encryptedData, secretKey);
        const requestData = JSON.parse(decryptedData);

        console.log('Received and decrypted data:', requestData);
        res.writeHead(200);
        res.end('Success');
    } else {
        res.writeHead(401);
        res.end('Invalid signature');
    }
});

server.listen(8443);

关键点

  1. 加密和签名过程:客户端在发送请求之前对数据进行加密和签名,以保证数据的机密性和完整性。
  2. 传输安全:HTTP/2通过SSL/TLS提供传输层的加密,确保传输过程中的安全。
  3. 数据验证和解密:服务器在接收到请求后,首先验证签名,然后解密数据,确保数据的来源和完整性。