目录
一、Base64编码
二、哈希算法
三、对称加密(AES/DES)
四、非对称加密(RSA)
五、加盐
六、Web Cryptography API
七、总结
随着信息和数据安全紧张性的日益凸显,如何包管信息数据在传输的过程中的安全成为开发者重点关注的内容。前端加密通常是指在浏览器中对各种传输的数据进行各种加密操作。然而前端加密更多的是用来对传输的数据进行简单的混淆,为了确保数据在传输过程中不被容易的窜改和读取。可供我们选择的加密方式有许多种,必要我们在开发过程中根据现实的场景选择适合自己的加密办理方案。那么,本文将联合应用场景来介绍一下前端开发中常用的加密方法。
一、Base64编码
严格意义上来说,Base64并不是一种加密方式,它是一种编码方式。Base64就是一种基于64个可打印字符来表现二进制数据的方法。Base64,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集,任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,必要解码后才能阅读。Base64由于以上优点被广泛应用于计算机的各个领域。JavaScript中可以利用内置的btoa函数进行Base64编码。btoa函数可以将二进制数据转换为Base64编码的字符串,同样也可利用内置函数atob对编码后的字符串进行解码。
- // 编码
- const base64Str = window.btoa('Hello World!');
- console.log(base64Str); // SGVsbG8gV29ybGQh
- // 解码
- const str = window.atob(base64Str);
- console.log(str); // Hello World!
复制代码 当然,我们也可以利用base64插件。
利用方法:
- import { Base64 } from 'js-base64';
- // 编码
- const encode = Base64.encode('Hello World!');
- console.log(encode);
- // 解码
- const decode = Base64.decode(encode);
- console.log(decode);
复制代码 二、哈希算法
散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从恣意文件中创造小的数字”指纹“的方法。与指纹一样,散列算法就是一种以较短的信息来包管文件唯一性的标志,这种标志与文件的每一个字节都相干,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件利用者当前的文件已经不是你所需求的文件。
Hash 算法能将将恣意长度的二进制明文映射为较短的二进制串的算法,并且差异的明文很难映射为相同的 Hash 值。
哈希算法(Hash Algorithm)是一种将恣意长度的消息映射为固定长度的消息摘要(Message Digest)的算法。哈希算法可以将恣意长度的输入数据转换为固定长度的输出,通常称为哈希值(Hash Value)或摘要(Digest),并且满足以下特性:
(1) 确定性:对于相同的输入数据,哈希算法会天生相同的哈希值。
(2) 不可逆性:无法从哈希值中推导出原始的输入数据。
(3) 唯一性:差异的输入数据天生的哈希值应尽可能差异。
(4) 散列性:即使输入数据仅有微小的变化,天生的哈希值应该有很大的差异。
因此,哈希算法广泛应用于密码学、数据完整性校验、数字署名、数据分片等领域。
(1) 数字署名:将原始数据的哈希值与署名一起存储,以验证署名的完整性和正确性。
(2) 密码存储:将用户密码的哈希值存储在数据库中,以制止直接存储明文密码,提高安全性。
(3) 数据完整性校验:将原始数据的哈希值与传输过程中的哈希值进行比对,以判断数据是否被窜改。
(4) 数据分片:将原始数据分成若干个块,对每个块分别计算哈希值,以便快速检测数据块的正确性。
比较常见的哈希算法有MD5、SHA-1、SHA-256和SHA-512等。
安装crypto-js:
利用方法:
- import CryptoJS from "crypto-js";
-
- // MD5
- const hash = CryptoJS.MD5('Message');
- // SHA-1
- const hash = CryptoJS.SHA1('Message');
- // SHA-256
- const hash = CryptoJS.SHA256('Message');
- // SHA-512
- const hash = CryptoJS.SHA512('Message');
复制代码 三、对称加密(AES/DES)
DES全称为Data Encryption Standardy即数据加密尺度,是一种利用密钥加密的算法。
AES全称为Advanced Encryption Standard,AES 算法利用分组密码体制,将明文按照固定巨细进行分组,然后对每一分组进行加密。在加密过程中,AES 算法采用了多轮加密的方式,每一轮加密都包含了四种操作:SubBytes、ShiftRows、MixColumns 和 AddRoundKey。通过这些操作,AES 算法可以更加安全高效地对数据进行加密。
AES和DES加密算法是一种对称加密方式,所谓对称加密就是加密与解密利用的秘钥(一组字符串)是一个。加密和解密端必须利用同一个密钥的才可以进行加密和解密。
AES 加密最常用的模式就是 ECB模式和CBC模式,当然另有许多别的模式,它们都属于AES加密。ECB模式和CBC模式俩者区别就是 ECB 不必要 iv偏移量,而CBC必要。
ECB是一种基础的加密方式,密文被分割成分组长度相等的块(不敷补齐),然后单独一个个加密,一个个输出构成密文。CBC是一种循环模式,前一个分组的密文和当前分组的明文异或或操作后再加密,如许做的目标是增强破解难度。
参数Mode为DES/AES的工作方式。
参数padding为填充模式,假如加密后密文长度假如达不到指定整数倍(8个字节、16个字节),填充对应字符,padding的赋值固定为CryptoJS.pad.Pkcs7即可。
- import CryptoJS from "crypto-js";
-
- //秘钥
- const secretKey = CryptoJS.enc.Utf8.parse("12345678ABCDEFGH"); //16位
- // iv偏移量
- const iv = CryptoJS.enc.Utf8.parse("ABCDEFGH12345678");
- // 需要加密的参数,数据类型为bytes
- const secretMessage = "Hello World!";
- // 加密
- const encrypt = CryptoJS.AES.encrypt(secretMessage, secretKey, {
- iv: iv,
- mode: CryptoJS.mode.CBC,
- padding: CryptoJS.pad.Pkcs7
- }).tostring();
- console.log(encrypt);
- //解密
- const decrypt = CryptoJS.AES.decrypt(encrypt, secretKey, {
- iv: iv,
- mode: CryptoJS.mode.CBC,
- padding: CryptoJS.pad.Pkcs7
- }).toString(CryptoJS.enc.Utf8);
- console.log(decrypt);
复制代码 四、非对称加密(RSA)
非对称加密,加密和解密的秘钥不是同一个秘钥,这里必要两把钥匙,一个公钥, 一个私钥, 公钥发送给客户端。发送端用公钥对数据进行加密,再发送给接收端,接收端利用私钥来对数据解密。由于私钥只存放在接受端这边,以是即使数据被截获了,也是无法进行解密的。
公钥与私钥是一对,由于加密和解密利用的是两个差异的密钥,以是这种算法叫作非对称加密算法。利用时都是利用公匙加密利用私匙解密。公匙可以公开,私匙自己保留。这个公钥和私钥其实就是一组数字,其二进制位长度可以是1024位大概2048位。长度越长其加密强度越大,相对就比较安全。以是目前为止,这种加密算法不停被广泛利用。
常见的非对称加密算法有RSA,DSA等等,本文我们就介绍一个RSA加密,也是最常见的一种加密方案。
jsencrypt就是一个基于RSA加解密的js库。
- npm install jsencrypt
- import JSEncrypt from 'jsencrypt'
- // RSA加密
- // 创建加密对象实例
- const encryptor = new JSEncrypt();
- //之前ssl生成的公钥,复制的时候要小心不要有空格
- const pubKey = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1QQRl0HlrVv6kGqhgonD6A9SU6ZJpnEN+Q0blT/ue6Ndt97WRfxtSAs0QoquTreaDtfC4RRX4o+CU6BTuHLUm+eSvxZS9TzbwoYZq7ObbQAZAY+SYDgAA5PHf1wNN20dGMFFgVS/y0ZWvv1UNa2laEz0I8Vmr5ZlzIn88GkmSiQIDAQAB-----END PUBLIC KEY-----';
- //设置公钥
- encryptor.setPublicKey(pubKey);
- // 对内容进行加密
- const encrypted = encryptor.encrypt('要加密的内容')
- // RSA解密
- //创建解密对象实例
- const decrypt = new JSEncrypt();
- //之前ssl生成的秘钥
- const priKey = '-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQC1QQRl0HlrVv6kGqhgonD6A9SU6ZJpnEN+Q0blT/ue6Ndt97WRfxtSAs0QoquTreaDtfC4RRX4o+CU6BTuHLUm+eSvxZS9TzbwoYZq7ObbQAZAY+SYDgAA5PHf1wNN20dGMFFgVS/y0ZWvv1UNa2laEz0I8Vmr5ZlzIn88GkmSiQIDAQABAoGBAKYDKP4AFlXkVlMEP5hS8FtuSrUhwgKNJ5xsDnFV8sc3yKlmKp1a6DETc7N66t/Wdb3JVPPSAy+7GaYJc7IsBRZgVqhrjiYiTO3ZvJv3nwAT5snCoZrDqlFzNhR8zvUiyAfGD1pExBKLZKNH826dpfoKD2fYlBVOjz6i6dTKBvCJAkEA/GtL6q1JgGhGLOUenFveqOHJKUydBAk/3jLZksQqIaVxoB+jRQNOZjeSO9er0fxgI2kh0NnfXEvH+v326WxjBwJBALfTRar040v71GJq1m8eFxADIiPDNh5JD2yb71FtYzH9J5/d8SUHI/CUFoROOhxr3DpagmrnTn28H0088vubKe8CQDKMOhOwx/tS5lqvN0YQj7I6JNKEaR0ZzRRuEmv1pIpAW1S5gTScyOJnVn1tXxcZ9xagQwlT2ArfkhiNKxjrf5kCQAwBSDN5+r4jnCMxRv/Kv0bUbY5YWVhw/QjixiZTNn81QTk3jWAVr0su4KmTUkg44xEMiCfjI0Ui3Ah3SocUAxECQAmHCjy8WPjhJN8y0MXSX05OyPTtysrdFzm1pwZNm/tWnhW7GvYQpvE/iAcNrNNb5k17fCImJLH5gbdvJJmCWRk=-----END RSA PRIVATE KEY----';
- //设置秘钥
- decrypt.setPrivateKey(priKey);
- //解密之前拿公钥加密的内容
- const uncrypted = decrypt.decrypt(encrypted)
复制代码
RSA加解密可以应用在用户注册或登录的时候,用公钥对密码进行加密,再去传给背景,背景用私钥对加密的内容进行解密,然后进行密码校验大概保存到数据库。
- 对称加密
- 两边共享密钥(码)(secret key,あんごう),加密传输基于密钥安全而非算法安全。
- 加密与解密利用同一算法。
- 破解难度主要取决于密钥复杂度。
- 非对称加密(公开密钥加密)
- 利用密钥对(公钥 publickey、私钥 privatekey)。
- 不传递私钥。
- 加解密可能利用多种规则和算法。
- 安全性既不依赖算法的保密,也不依赖于传递密钥的途径。
比特币和以太坊加密技术
大量利用对称加密和非对称加密,以及相干技术。
- 加密、解密(如上述)
- Hash、Message digest(哈希,SHA256, RIPEMD160)
- Checksum(校验和)
- 编码(Base64,Base58)
^ Hash: 摘要,对不定长度的数据进行换算,计算出固定长度的不容易辩说的结果。
^ Checksum:校验和,对数据进行冗余校验和完整性检查。
^ 编码:将二进制数据转化为平常字符,更易于阅读和辨别。
五、加盐
加盐是指在密码哈希过程中引入一个随机天生的字符串,称为盐(salt),并将其与密码进行组合后再进行哈希计算。这个盐值会与每个用户的密码单独关联,并且将其存储在数据库中。加盐可以增加密码哈希的复杂度,提高密码的安全性,即使两个用户利用相同的密码,由于利用了差异的盐值,其哈希结果也会有所区别。如许即使黑客获得了哈希值,也很难通过暴力破解找到原始的密码。
盐值其实就是我们添加的一串随机字符串(这个值可以是固定值、随机数、uuid……),相同的字符串每次都会被加密为完全差异的字符串。
利用加盐加密时必要注意以下两点:
(1)短盐值(Short Slat)
假如盐值太短,攻击者可以预先制作针对所有可能的盐值的查询表。比方,假如盐值只有三个 ASCII 字符,那么只有 95x95x95=857,375 种可能性,加大了被攻击的可能性。另有,不要利用可预测的盐值,好比用户名,由于针对某系统用户名是唯一的且被常常用于其他服务。
(2)盐值复用(Salt Reuse)
在项目开发中,偶然会碰到将盐值写死在步伐里大概只有第一次是随机天生的,之后都会被重复利用,这种加盐方法是不起作用的。以登录密码为例,假如两个用户有相同的密码,那么他们就会有相同的哈希值,攻击者就可以利用反向查表法对每个哈希值进行字典攻击,使得该哈希值更容易被破解。
以是正确的加盐方法如下:
(1)盐值应该利用加密的安全伪随机数天生器( Cryptographically Secure Pseudo-Random Number Generator,CSPRNG )产生,好比 C 语言的 rand() 函数,如许天生的随机数高度随机、完全不可预测;
(2)盐值混入目标文本中,一起利用尺度的加密函数进行加密;
(3)盐值要充足长(履历表明:盐值至少要跟哈希函数的输出一样长)且永不重复;
(4)盐值最好由服务端提供,前端取值利用。
我们一起SHA-256为例实现加盐加密。
安装js-sha256
利用方法:
- import { sha256 } from 'js-sha256';
-
- const generateSalt = () => {
- const randomBytes = new Uint8Array(16);
- crypto.getRandomValues(randomBytes);
- return Array.from(randomBytes, (byte) =>
- byte.toString(16).padStart(2, '0')
- ).join('');
- };
- // 盐值
- const salt = generateSalt();
- // 假如一个密码
- const password = 'admin123456';
- // 盐值和密码进行组合
- const saltedPassword = salt + password;
- // 哈希计算
- const hash = sha256(saltedPassword);
- console.log(hash);
复制代码 六、Web Cryptography API
Web Cryptography API(WebCrypto API)是现代浏览器内置的一个加密尺度,可以用于更安全的密码学操作。这个API允许我们在Web应用中实现加密、解密、数字署名等安全功能,而无需依赖第三方库或插件。
WebCrypto API是W3C的尺度,它提供了一套低级别的接口用于执行各种密码学操作。这些接口包括:
天生和管理密钥:如RSA、AES和HMAC等。
加密和解密:支持多种对称和非对称加密算法。
摘要和哈希:如SHA-1、SHA-256和MD5等。
数字署名和验证:用于确保数据的完整性和泉源真实性。
随机数天生:用于创建安全的随机数。
window.crypto.subtle就是SubtleCrypto接口,主流最新浏览器基本都已经支持该接口,并且一致,除了safari必要注意。
- // fix safari crypto namespace
- if (window.crypto && !window.crypto.subtle && window.crypto.webkitSubtle) {
- window.crypto.subtle = window.crypto.webkitSubtle;
- }
- /**
- * Detect Web Cryptography API
- * @return {Boolean} true, if success
- */
- function isWebCryptoAPISupported() {
- return 'crypto' in window && 'subtle' in window.crypto;
- }
复制代码
getRandomValues 同步方法,获取随机数,由于性能要求,这是一个伪随机数天生器(PRNG)。浏览器也通过添加系统级别的种子来提高熵(不确定性的量度),来满足密码学利用要求。
- const size = 10;
- const array = new Uint8Array(size);
- window.crypto.getRandomValues(array);
- // print values to console
- for (let i=0; i!==array.length; ++i) {
- console.log(array[i]);
- }
复制代码
SubtleCrypto接口:
encrypt、decrypt(加解密方法),算法支持:RSA-OAEP、AES-CTR、AES-CBC、AES-GCM、AES-CFB。
Sign、verify(署名验签发方法),算法支持:RSASSA-PKCS1-v1.5、RSA-PSS、ECDSA、AES-CMAC、HMAC。
Digest(摘要方法),算法支持:SHA-1、SHA-256、SHA-384、SHA-512。
GenerateKey:天生对称/非对称的密钥(CryptoKey对象)。
DeriveKey 和 deriveBits:从原密钥或是从伪随机函数天生的密码/口令中天生出一个密钥。
WrapKey 和 unwrapKey:用来保护在不安全信道或不可信环境存储的密钥的方法。
ImportKey 和 exportKey:导入密钥,转换再导出差异格式。
上面的方法都会返回Promise。
以下是利用WebCrypto API实现一个简单的加密,代码如下:
- // 生成公钥和私钥
- const keyPair = await window.crypto.subtle.generateKey(
- {
- name: "RSA-OAEP", // 使用RSA-OAEP算法
- modulusLength: 2048, // 密钥长度为2048位
- publicExponent: new Uint8Array([1, 0, 1]), // 公共指数为65537
- hash: "SHA-256" // 哈希算法为SHA-256
- },
- true, // 生成可导出的密钥对
- ["encrypt", "decrypt"] // 可用于加密和解密操作
- );
- keyPair.then(function(result) {
- // 处理生成的密钥对
- console.log(result.publicKey); // 打印公钥
- console.log(result.privateKey); // 打印私钥
- }).catch(function(error) {
- // 处理错误
- console.error(error);
- });
- // 加密
- async function encryptByRSA(message, publicKey) {
- // 将消息编码为Uint8Array格式
- const encodedMessage = new TextEncoder().encode(message);
- // 使用Web Crypto API的encrypt()方法对消息进行加密
- const encrypted = await window.crypto.subtle.encrypt(
- {
- name: "RSA-OAEP" // 加密算法为RSA-OAEP
- },
- publicKey, // 使用传入的公钥进行加密
- encodedMessage // 要加密的消息
- );
- // 将加密后的数据转换为Base64编码的字符串
- return window.btoa(String.fromCharCode(...new Uint8Array(encrypted)));
- }
-
- // 解密 使用RSA私钥对密文进行解密
- async function decryptByRSA(ciphertext, privateKey) {
- // 将Base64编码的密文解码为Uint8Array格式
- const decodedCiphertext = Uint8Array.from(
- atob(ciphertext),
- c => c.charCodeAt(0)
- );
- // 使用Web Crypto API的decrypt()方法对密文进行解密
- const decrypted = await window.crypto.subtle.decrypt(
- {
- name: "RSA-OAEP" // 解密算法为RSA-OAEP
- },
- privateKey, // 使用传入的私钥进行解密
- decodedCiphertext // 要解密的密文
- );
- // 将解密后的数据转换为字符串
- return new TextDecoder().decode(decrypted);
- }
复制代码
七、总结
以上几种加密方法提供了基本的前端加密方法。大部分时候,为了确保数据的安全性,会将一些敏感数据(如手机号、身份证号、银行卡号等)发送到服务端,然后再服务端进行加密。前端加密并不能确保数据的安全性,由于客户端是暴露给用户的,任何混淆或加密措施都可能被绕过(前端加密防君子不放小人)。正确的做法是在包管数据传输过程中通过HTTPS等协议加密,并在服务端进行必要的安全校验和加密处理处罚。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |