欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 前后端分离技术之加签,验签,报文防篡改

前后端分离技术之加签,验签,报文防篡改

2025/2/24 8:55:09 来源:https://blog.csdn.net/qq_52183856/article/details/144448984  浏览:    关键词:前后端分离技术之加签,验签,报文防篡改

1.场景

最近项目上被渗透扫到可以通过篡改后端返回的报文,来使前端跳过校验进入下一步操作

2.解决方法

通过后端RSA非对称加密方式,对返回的数据使用私钥进行加密,增加返回参数sign,前端使用公钥来对相同的数据加密,通过对比生成的sign来判断数据是否存在篡改的情况。

1.前端引入依赖
"node-forge": "^1.3.0"
2.生成一对秘钥,前端存放公钥,后端存放私钥
const forge = require('node-forge');
const pki = forge.pki;
// 生成 RSA 密钥对 (512 位)
const keys = pki.rsa.generateKeyPair(512);
// 将私钥转换为 PEM 格式
const privateKeyPem = pki.privateKeyToPem(keys.privateKey);
console.log('Private Key (PEM):\n', privateKeyPem);
// 将公钥转换为 PEM 格式
const publicKeyPem = pki.publicKeyToPem(keys.publicKey);
console.log('Public Key (PEM):\n', publicKeyPem);
3.后端使用私钥对数据进行加密
3.1工具类
public class RSAUtil {/*** 获取公钥* * @param publicKey 公钥字符串* @return*/public static PublicKey getPublicKey(String publicKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);return keyFactory.generatePublic(keySpec);}/*** 签名* * @param data 待签名数据* @param privateKey 私钥* @return 签名*/public static String sign(String data, PrivateKey privateKey) throws Exception {byte[] keyBytes = privateKey.getEncoded();PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(key);signature.update(data.getBytes());return new String(Base64.encodeBase64(signature.sign()));}/*** 验签* * @param srcData 原始字符串* @param publicKey 公钥* @param sign 签名* @return 是否验签通过*/public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {byte[] keyBytes = publicKey.getEncoded();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey key = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance("SHA256withRSA");signature.initVerify(key);signature.update(srcData.getBytes());return signature.verify(Base64.decodeBase64(sign.getBytes()));}
3.2后端使用私钥加密数据,生成sign一并返回前端
		Boolean flag = (Boolean) map.get("flag");Long timeStamp = System.currentTimeMillis();stringMap.put("flag", String.valueOf(flag));//签名的生成增加时间戳stringMap.put("timeStamp", String.valueOf(timeStamp));//使用私钥进行签名生成String signature = RSAUtil.sign(JSON.toJSONString(stringMap), RSAUtil.getPrivateKey(SystemHashMap.systemHashMap.get("YDSC_ORDER_RSA_PRIVATE_KEY")));map.put("timeStamp", timeStamp);map.put("signature", signature);
4.前端进行加密相同数据验签
4.1.对后端返回的数据使用公钥加密,验签
verifySignature(response) {const json = {flag: response.flag,timeStamp: response.timeStamp,};const data = JSON.stringify(json);const md = forge.md.sha256.create();md.update(data, 'utf8');//验签const signature = forge.util.decode64(response.signature);// 将PEM格式的公钥转换为Forge公钥对象const publicKey = forge.pki.publicKeyFromPem(this.publicKey);// 验证签名const verified = publicKey.verify(md.digest().bytes(), signature);return verified;}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词