数字签名、信息加密 是前后端开发都经常需要使用到的技术,应用场景包括了用户登入、交易、信息通讯、oauth 等等,不同的应用场景也会需要使用到不同的签名加密算法,或者需要搭配不一样的 签名加密算法 来达到业务目标。这里简单的给大家介绍几种常见的签名加密算法和一些典型场景下的应用。
数字签名又称公钥数字签名,是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。
简单来说就是通过提供 可鉴别 的 数字信息 验证 自身身份 的一种方式。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。分别由 发送者 持有能够 代表自己身份 的 私钥 (私钥不可泄露),由 接受者 持有与私钥对应的 公钥 ,能够在 接受 到来自发送者信息时用于 验证 其身份。
加密
数据加密 的基本过程,就是对原来为 明文 的文件或数据按 某种算法 进行处理,使其成为 不可读 的一段代码,通常称为 “密文”。通过这样的途径,来达到 保护数据 不被 非法人窃取、阅读的目的。
解密
加密 的 逆过程 为 解密,即将该 编码信息 转化为其 原来数据 的过程。
散列算法是一种常见的加密技术,一般也被称为哈希算法或哈希函数。
Hash算法特别的地方在于它是一种单向算法,用户可以通过hash算法对目标信息生成一段特定长度的唯一hash值,却不能通过这个hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。
常见的Hash算法有MD2、MD4、MD5、HAVAL、SHA
加密算法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
MD5 | 简单快速,生成结果固定长度(128位),广泛应用于校验数据完整性。 | 安全性较低,容易受到碰撞攻击,即找到两个不同的输入数据产生相同的摘要。 | 文件校验、密码存储等对安全性要求不高的场景。 |
SHA-1 | 生成结果较MD5更长(160位),安全性相对较高,被广泛使用。 | 随着计算能力的提升,SHA-1也逐渐出现碰撞攻击的风险 | 数字证书、版本控制、文件完整性验证等。 |
SHA-256 | 优点:生成结果更长(256位),安全性更高,抗碰撞能力强。 | 缺点:计算比较耗时,相对于较短散列算法有一定的性能损失。 | 使用场景:密码学安全场景、区块链、数字货币等对安全性要求较高的场景。 |
SHA-3 | 新一代的散列算法,与SHA-2相比,在设计和安全性上进行了改进。 | 计算量相对较大,相对于SHA-2有一定的性能损失。 | 密码学安全、数字签名等需要高级安全性的场景。 |
HMAC | 结合散列函数和密钥,提供更高的安全性和消息完整性验证。 | 需要密钥管理,不当使用可能引入密钥泄露和伪装攻击的风险。 | 身份认证、防止篡改等场景,如网络通信中的数据完整性校验。 |
MD5 用的是 哈希函数,它的典型应用是对一段信息产生 信息摘要,以 防止被篡改。严格来说,MD5 不是一种 加密算法 而是 摘要算法。无论是多长的输入,MD5 都会输出长度为 128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。
前端使用vue,后端使用nodejs,实现md5加密:
在前端使用Vue,可以通过引入第三方库如js-md5来实现MD5加密。首先,在你的Vue项目中安装该库:
npm install js-md5
在需要进行加密的Vue组件中导入并使用js-md5库进行MD5加密。下面是一个示例:
// 导入js-md5库
import md5 from 'js-md5';
// 进行MD5加密
const encryptedString = md5('YourStringToEncrypt');
console.log(encryptedString); // 输出加密后的字符串
在后端使用Node.js,可以使用内置模块crypto来进行MD5加密。下面是一个示例:
// 导入crypto模块
const crypto = require('crypto');
// 创建md5哈希对象
const md5Hash = crypto.createHash('md5');
// 更新哈希对象的数据
md5Hash.update('YourStringToEncrypt');
// 获取最终的哈希值(加密后的字符串)
const encryptedString = md5Hash.digest('hex');
console.log(encryptedString); // 输出加密后的字符串
在 对称加密算法 中,使用的密钥只有一个,发送 和 接收 双方都使用这个密钥对数据进行 加密 和 解密。这就要求加密和解密方事先都必须知道加密的密钥。
数据加密过程:在对称加密算法中,数据发送方 将 明文 (原始数据) 和 加密密钥 一起经过特殊 加密处理,生成复杂的 加密密文 进行发送。
数据解密过程:数据接收方 收到密文后,若想读取原数据,则需要使用 加密使用的密钥 及相同算法的 逆算法 对加密的密文进行解密,才能使其恢复成 可读明文。
常见的对称加密算法有
DES、3DES、AES 、Blowfish、IDEA、RC4、RC5、RC6
弊端
假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要2个密钥并交换使用,如果企业内用户有n个,则整个企业共需要n×(n-1) 个密钥,密钥的生成和分发将成为企业信息部门的恶梦。
加密算法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
AES | 安全性高、速度快、广泛应用、可使用不同密钥长度。 | 对于某些特殊情况下的攻击(如侧信道攻击)可能存在漏洞。 | 适用于各种场景,包括数据传输、存储加密等。 |
DES | 历史悠久、广泛应用、实现简单。 | 密钥长度较短(56位),易受到暴力破解攻击;安全性相对较低。 | 在需要保密性要求不是非常高的场景中仍然可以使用,但已经逐渐被更安全的算法替代。 |
3DES | 对于DES算法来说,提供了更高的安全性;密钥长度为112或168位。 | 相比AES,速度较慢、效率低 | 在需要向后兼容使用DES算法的系统中可以考虑使用3DES进行加密。 |
Blowfish | 安全性较高、速度快、密钥长度可变 | 在某些特定情况下,可能存在安全性漏洞。 | 用于需要高速处理大量数据的场景,如虚拟私有网络(VPN)和加密存储。 |
RC4 | 速度较快,适用于对传输效率要求较高的场景。 | 由于存在一些安全漏洞,在许多情况下已不推荐使用。 | 过去常用于保护流媒体、无线通信等场景,但现在不再推荐使用。 |
AES 加密算法是密码学中的 高级加密标准,该加密算法采用 对称分组密码体制,密钥长度的最少支持为 128 位、 192 位、256 位,分组长度 128 位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的 区块加密标准。
AES 本身就是为了取代 DES 的,AES 具有更好的 安全性、效率 和 灵活性。
要在前端使用Vue和后端使用Node.js实现AES加密,你可以按照以下步骤进行操作:
在前端使用Vue:
在你的Vue项目中安装第三方库crypto-js,该库提供了AES加密和解密的功能。
npm install crypto-js
在需要进行AES加密和解密的Vue组件中导入并使用crypto-js库。下面是一个示例:
// 导入crypto-js库
import CryptoJS from 'crypto-js';
// 定义密钥和待加密的数据
const key = 'YourSecretKey';
const data = 'YourDataToEncrypt';
// 进行AES加密
const encryptedData = CryptoJS.AES.encrypt(data, key).toString();
console.log(encryptedData); // 输出加密后的数据
// 进行AES解密(使用相同的密钥)
const decryptedData = CryptoJS.AES.decrypt(encryptedData, key).toString(CryptoJS.enc.Utf8);
console.log(decryptedData); // 输出解密后的数据
在后端使用Node.js:
在你的Node.js项目中安装第三方库crypto-js,同样提供了AES加密和解密的功能。
npm install crypto-js
在需要进行AES加密和解密的Node.js文件中导入并使用crypto-js库。下面是一个示例:
// 导入crypto-js库
const CryptoJS = require('crypto-js');
// 定义密钥和待加密的数据
const key = 'YourSecretKey';
const data = 'YourDataToEncrypt';
// 进行AES加密
const encryptedData = CryptoJS.AES.encrypt(data, key).toString();
console.log(encryptedData); // 输出加密后的数据
// 进行AES解密(使用相同的密钥)
const decryptedData = CryptoJS.AES.decrypt(encryptedData, key).toString(CryptoJS.enc.Utf8);
console.log(decryptedData); // 输出解密后的数据
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。
如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。
举例:
甲方生成 一对密钥 并将其中的一把作为 公钥 向其它人公开,得到该公钥的 乙方 使用该密钥对机密信息 进行加密 后再发送给甲方,甲方再使用自己保存的另一把 专用密钥 (私钥),对 加密 后的信息 进行解密。
非对称加密的典型应用是数字签名。
常见的非对称加密算法有:
RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)
加密算法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
RSA | 安全性高,使用广泛 | 加密和解密速度慢 | 适用于对少量数据进行加密 |
ElGamal | 安全性高 | 加密和解密速度慢 | 适用于对少量数据进行加密 |
Rabin | 安全性高,基于大质数分解的困难性 | 加密和解密速度慢 | 适用于对少量数据进行加密 |
DSA | 速度快,安全性与RSA相比差不多 | 只能用于签名,不能用作加密和解密或进行密钥交换 | 适用于验证数字签名的真实性 |
ECDSA | 速度快,安全性与RSA相比差不多 | 只能用于签名,不能用作加密和解密或进行密钥交换 | 适用于验证数字签名的真实性 |
RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一。RSA 是第一个能同时用于 加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已被 ISO 推荐为公钥数据加密标准。
在前端使用Vue和后端使用Node.js实现RSA加密和解密的过程如下:
在前端使用Vue:
在你的Vue项目中安装第三方库jsencrypt,该库提供了RSA加密和解密的功能。
npm install jsencrypt
在需要进行RSA加密的Vue组件中导入并使用jsencrypt库。下面是一个示例:
// 导入jsencrypt库
import JSEncrypt from 'jsencrypt';
// 创建RSA对象
const rsa = new JSEncrypt();
// 设置公钥(从后端获取)
const publicKey = '-----BEGIN PUBLIC KEY-----\nYourPublicKey\n-----END PUBLIC KEY-----';
rsa.setPublicKey(publicKey);
// 待加密的数据
const data = 'YourDataToEncrypt';
// 进行RSA加密
const encryptedData = rsa.encrypt(data);
console.log(encryptedData); // 输出加密后的数据
在后端使用Node.js:
在你的Node.js项目中安装第三方库node-rsa,同样提供了RSA加密和解密的功能。
npm install node-rsa
在需要进行RSA解密的Node.js文件中导入并使用node-rsa库。下面是一个示例:
// 导入node-rsa库
const NodeRSA = require('node-rsa');
// 创建RSA对象
const rsa = new NodeRSA();
// 设置私钥(从前端传递或者本地读取)
const privateKey = `-----BEGIN PRIVATE KEY-----
YourPrivateKey
-----END PRIVATE KEY-----`;
rsa.importKey(privateKey, 'pkcs8-private-pem');
// 待解密的数据
const data = 'YourEncryptedData';
// 进行RSA解密
const decryptedData = rsa.decrypt(data, 'utf8');
console.log(decryptedData); // 输出解密后的数据