深入了解SM
在前端开发的日常工作中,从网页上的表单提交,到与后端服务器的数据交互,每一个环节都离不开信息的传输与处理。而这些信息里,既有用户输入的账号密码、地址电话等个人隐私,也可能涉及企业的商业机密。一旦安全防线出现漏洞,就如同敞开大门任由不法分子肆意妄为,隐私泄露、数据篡改等风险便会接踵而至。这不仅会让用户在使用过程中遭遇卡顿、错误提示甚至账号被盗等糟糕体验,还可能致使企业面临巨额赔偿与形象崩塌的危机。在此背景下,我国自主可控的 SM 加密体系,以其卓越的加密性能与安全性,为前端信息安全筑牢了一道坚不可摧的防护墙,助力前端开发者守护好用户与企业的数据资产。
SM 加密体系详解
SM1 算法
SM1 是一种分组密码算法,分组长度和密钥长度均为 128 位,加密强度与 AES 相当,但算法细节保密,这让它在高安全场景更具优势。
比如金融 IC 卡的安全芯片,存储着用户关键信息。刷卡时,芯片与设备间通过 SM1 算法将明文转为密文,芯片的物理防护机制,如金属屏蔽和防篡改电路,能抵御物理攻击和数据窃取,确保交易安全,守护用户财富。
SM2 算法
SM2 属于非对称加密算法,基于椭圆曲线密码体制。相比 RSA,在同等安全强度下,SM2 密钥长度更短,仅需 256 位。在电子政务数字签名认证中,工作人员用 SM2 私钥给公文签名,接收方用其公钥验证,以此确认公文未被篡改。在密钥交换时,双方用 SM2 协商出对称加密密钥,用于后续数据传输,极大提升通信效率。
在 JavaScript 中实现 SM2 算法相关操作,可借助sm-crypto
库。首先需安装该库,在项目目录下运行npm install sm-crypto
。以下是一个简单的生成 SM2 密钥对的代码示例:
const smCrypto = require('sm-crypto');
// 生成SM2密钥对
const keyPair = smCrypto.generateKeyPair('sm2');
const privateKey = keyPair.privateKey;
const publicKey = keyPair.publicKey;
console.log('SM2私钥:', privateKey);
console.log('SM2公钥:', publicKey);
SM3 算法
SM3 是一种哈希算法,能将任意长度的输入消息压缩成 256 位哈希值。在文件传输前,发送方用 SM3 算出文件的哈希摘要,作为 “数字指纹”。接收方收到文件后,会用 SM3 重新计算哈希值,与接收到的哈希摘要比对。若二者一致,说明文件未被篡改;若不一致,文件可能已被修改,接收方需采取相应措施。
使用sm-crypto
库计算文件 SM3 哈希值的 JavaScript 代码如下,假设文件内容通过fs.readFileSync
读取为字符串fileContent
:
const smCrypto = require('sm-crypto');
const fs = require('fs');
// 读取文件内容
const fileContent = fs.readFileSync('example.txt', 'utf8');
// 计算SM3哈希值
const hash = smCrypto.sm3(fileContent);
console.log('文件的SM3哈希值:', hash);
SM4 算法
SM4 是一种 128 位分组和密钥长度的对称加密算法,在 VPN 通信中至关重要。企业员工远程通过 VPN 访问内部网络时,员工设备与公司 VPN 服务器间会建立加密通道。SM4 算法会在数据传输前将其加密为密文,即便数据被第三方截取,没有 128 位密钥也无法还原真实内容,从而保障了企业网络资源的安全与数据保密性。
以下是使用sm-crypto
库进行 SM4 加密和解密的 JavaScript 代码示例:
const smCrypto = require('sm-crypto');
// 待加密数据
const plaintext = '这是需要加密的数据';
// 128位密钥,需妥善保管
const key = '1234567890123456';
// SM4加密
const ciphertext = smCrypto.sm4.encrypt(plaintext, key);
console.log('SM4加密后的密文:', ciphertext);
// SM4解密
const decryptedText = smCrypto.sm4.decrypt(ciphertext, key);
console.log('SM4解密后的明文:', decryptedText);
SM7 算法
SM7 同样是国密算法家族中的重要成员,主要聚焦于非接触式 IC 卡领域,常见的公交卡、门禁卡等都运用了 SM7 算法。其分组长度和密钥长度同样为 128 位,具备较高的安全性与出色的运行效率。以公交卡系统为例,乘客手持公交卡靠近刷卡设备时,卡片与刷卡设备瞬间完成数据交互。在此过程中,乘客的个人信息(如姓名、卡号等)、余额信息等敏感数据通过 SM7 算法加密传输,既保证了信息不被泄露,又凭借算法高效的运算速度,能够在极短时间内完成交易验证,实现快速扣费,大大提升了乘客的出行体验与公共交通系统的运营效率。
SM9 算法
SM9 属于标识密码算法,是一种极具创新性的非对称加密算法。与传统非对称加密算法依赖复杂的数字证书体系不同,SM9 另辟蹊径,将用户的标识(如邮件地址、手机号码等)直接作为公钥使用,极大地简化了公钥管理流程,省略了繁琐的数字证书申请、颁发和管理过程。在端对端离线安全通讯场景中,其优势体现得淋漓尽致。例如,在一些自然灾害后的应急通信场景下,救援人员之间无法依赖常规的网络基础设施与数字证书体系。但借助 SM9 算法,他们只需知晓对方的手机号码,就可以直接进行安全通信。通过特定的加密运算,将信息加密后传输,确保救援指令、受灾情况等关键信息在传输过程中的安全性与完整性。
SM 加密实战:混合加密应用
实战场景设定
假设我们要构建一个安全性能极高的文件传输系统,该系统必须全方位保证文件在传输过程中的保密性、完整性和不可否认性。为达成这一目标,我们将采用混合加密的精妙方式,有机结合 SM2、SM3 和 SM4 算法,充分发挥各算法的优势。
具体实现步骤
密钥生成:发送方首先启动 SM2 算法,通过一系列复杂的数学运算,生成一对独一无二的密钥,即私钥和公钥。私钥如同发送方的 “数字保险柜钥匙”,必须由发送方采用极为安全的方式妥善保管,如存储在加密的硬件密钥设备中,防止任何形式的泄露。公钥则可以按照既定的安全流程公开给接收方,用于后续的加密与验证操作。在 JavaScript 中可参考前文生成 SM2 密钥对的代码实现。
文件哈希计算:发送方对待传输的文件调用 SM3 算法进行哈希值计算。算法会逐位读取文件内容,经过多轮复杂的变换与运算,最终得到一个 256 位的哈希摘要。这个哈希摘要就像文件的专属 “数字身份证”,文件内容哪怕只发生一个字节的变化,其哈希摘要也会截然不同,用于后续验证文件的完整性。可参考前文使用sm-crypto
库计算文件 SM3 哈希值的代码。
对称密钥生成与文件加密:发送方借助安全的随机数生成器,生成一个随机的 128 位 SM4 对称密钥。随后,利用这个对称密钥,依据 SM4 算法的加密规则,对文件进行加密操作。在加密过程中,文件被分割成若干个 128 位的分组,每个分组依次经过一系列的加密变换,最终得到加密后的文件密文,确保文件内容在传输过程中的保密性。可参考前文 SM4 加密的 JavaScript 代码示例,将待加密数据替换为文件内容。
对称密钥加密与签名:发送方使用接收方预先公开的 SM2 公钥,对刚才生成的 SM4 对称密钥进行加密处理。通过 SM2 算法的加密运算,将对称密钥转化为密文形式,只有拥有对应 SM2 私钥的接收方才能解密还原。同时,发送方使用自己的 SM2 私钥对文件的哈希摘要进行签名操作。依据 SM2 签名算法,生成一个数字签名,这个签名能够证明文件来源的真实性与完整性。在sm-crypto
库中可使用相应方法实现 SM2 加密对称密钥和对哈希摘要签名的操作,具体代码如下:
const smCrypto = require('sm-crypto');
// 假设已生成SM2密钥对
const senderPrivateKey = '发送方私钥';
const receiverPublicKey = '接收方公钥';
const sm4Key = '生成的SM4对称密钥';
const hashDigest = '文件的SM3哈希摘要';
// 使用接收方公钥加密SM4对称密钥
const encryptedSm4Key = smCrypto.sm2.encrypt(sm4Key, receiverPublicKey);
// 使用发送方私钥对哈希摘要签名
const signature = smCrypto.sm2.sign(hashDigest, senderPrivateKey);
数据传输:发送方将加密后的文件密文、加密后的对称密钥以及数字签名,按照特定的协议格式打包在一起,通过安全的网络通道发送给接收方。在传输过程中,数据可能会经过多个网络节点,面临各种潜在的安全风险,但由于加密与签名的保护,数据的安全性得到有效保障。在 JavaScript 实现中,可借助网络请求库(如axios
)将打包后的数据发送给接收方,示例代码如下:
const axios = require('axios');
// 假设已准备好要发送的数据
const dataToSend = {
encryptedFile: '加密后的文件密文',
encryptedSm4Key: '加密后的SM4对称密钥',
signature: '数字签名'
};
axios.post('接收方地址', dataToSend)
.then(response => {
console.log('数据发送成功:', response.data);
})
.catch(error => {
console.error('数据发送失败:', error);
});
接收方验证与解密:接收方收到数据后,首先调用发送方的 SM2 公钥,依据 SM2 验证算法对数字签名进行真实性验证。如果验证成功,便确认文件未被篡改且来源可靠。接着,接收方使用自己的 SM2 私钥解密加密后的对称密钥,还原出原始的 128 位 SM4 对称密钥。最后,接收方运用这个 SM4 对称密钥,按照 SM4 解密算法规则解密文件密文,得到原始文件。为进一步确保文件完整性,接收方再次使用 SM3 算法计算文件的哈希值,并与接收到的哈希摘要进行精确比对,双重验证文件在传输过程中的完整性。以下是接收方验证与解密的 JavaScript 代码示例:
const smCrypto = require('sm-crypto');
// 假设接收方已收到数据
const receivedEncryptedFile = '接收到的加密文件密文';
const receivedEncryptedSm4Key = '接收到的加密SM4对称密钥';
const receivedSignature = '接收到的数字签名';
const senderPublicKey = '发送方公钥';
const receiverPrivateKey = '接收方私钥';
// 验证签名
const isSignatureValid = smCrypto.sm2.verify(receivedSignature, receivedHashDigest, senderPublicKey);
if (isSignatureValid) {
// 解密SM4对称密钥
const decryptedSm4Key = smCrypto.sm2.decrypt(receivedEncryptedSm4Key, receiverPrivateKey);
// 解密文件
const decryptedFile = smCrypto.sm4.decrypt(receivedEncryptedFile, decryptedSm4Key);
// 重新计算文件哈希值并比对
const newHashDigest = smCrypto.sm3(decryptedFile);
if (newHashDigest === receivedHashDigest) {
console.log('文件验证与解密成功');
} else {
console.log('文件哈希值比对失败,文件可能被篡改');
}
} else {
console.log('签名验证失败,文件来源不可信');
}
结语
我们作为前端,平时最常用的就是SM2 SM3 SM4,希望这篇文章能给你带来帮助。让你对SM有个深刻的了解。