传输完整性要求
传输完整性是指确保信息在传输过程中不被篡改或损坏。在密评中,传输完整性的评估主要关注以下几个方面:
- 完整性校验机制:是否采用了消息鉴别码(MAC)或数字签名等技术对传输的信息进行完整性校验,以确保信息在传输过程中未被篡改。
- 错误检测与纠正:是否具备错误检测和纠正机制,以应对传输过程中可能出现的错误或损坏。
- 传输协议的完整性保护:传输协议是否提供了完整性保护机制,以确保信息在传输过程中的完整性。
技术方案
- 1、使用 HMAC/SM3: 使用 HMAC(散列消息认证码)/SM3(国密摘要签名算法)来验证数据的完整性。
- 2、数字签名: 使用数字签名来确保数据在传输过程中未被篡改。
方案-1: 前端在传输前对敏感数据进行数字签名
,后端服务进行签名验证
(外部加解密服务)
在方案-3、方案-4 中都是系统内部,前后端进行加密解密的操作,在一些场景中,加解密服务有专门的服务负责,前后端仅需求去调用接口即可
前端签名
在请求之前调用数字签名接口,进行签名
// TODO
后端验证
CryptoUtil
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import okhttp3.OkHttpClient;
import okhttp3.spring.boot.OkHttp3Template;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* 外部加解密工具类
*/
public class CryptoUtil {
private static OkHttpClient client;
private static OkHttp3Template okHttp3Template;
private static ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.enable(MapperFeature.USE_GETTERS_AS_SETTERS);
objectMapper.enable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS);
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
client = new OkHttpClient().newBuilder().connectTimeout(5000, TimeUnit.MILLISECONDS)
// .hostnameVerifier(okhttpHostnameVerifier)
// .followRedirects(properties.isFollowRedirects())
// .followSslRedirects(properties.isFollowSslRedirects())
.pingInterval(1, TimeUnit.MILLISECONDS).readTimeout(3000, TimeUnit.MILLISECONDS)
.retryOnConnectionFailure(true)
// .sslSocketFactory(trustedSSLSocketFactory, trustManager)
.writeTimeout(3, TimeUnit.SECONDS)
// Application Interceptors、Network Interceptors :
// https://segmentfault.com/a/1190000013164260
// .addNetworkInterceptor(loggingInterceptor)
// .addInterceptor(headerInterceptor)
.build();
okHttp3Template = new OkHttp3Template(client, objectMapper);
}
/**
* 调用加密接口
*/
public static String encrypt(String plainTxt) {
try {
return okHttp3Template.get("http://localhost:8080/encrypt?plainTxt=" + plainTxt, String.class);
} catch (IOException e) {
return null;
}
}
/**
* 调用解密接口
*/
public static String decrypt(String cipherTxt) {
try {
return okHttp3Template.get("http://localhost:8080/decrypt?plainTxt=" + cipherTxt, String.class);
} catch (IOException e) {
return null;
}
}
/**
* 调用签名接口
*/
public static String digest(String plainTxt) {
try {
return okHttp3Template.get("http://localhost:8080/digest?plainTxt=" + plainTxt, String.class);
} catch (IOException e) {
return null;
}
}
}
方案-2: 前端在传输前对敏感数据进行数字签名
,后端服务进行签名验证
(SM3 算法)
考虑到国内的情况,优先使用国密 SM3 算法,主要思路是前端在传输前对 Query 参数 和 Body 进行
SM3 摘要
,后端服务在 Gateway 统一进行SM3 摘要
和 对比
前端
- 1、安装 gm-crypt 包
npm install gm-crypt
- 2、封装js
sm3Util.js
import { SM4, SM3, SM2 } from 'gm-crypto';
const slat = 'xxx'; // 密钥 前后端一致即可,后端提供
/*
* 摘要签名函数
* @param {String} text 待加密文本
* @param key string 加密key(16位)
* @param iv string 偏移向量(16位)
*/
export function SM3Digest(text, slat = pwdKey, iv = pwdKey) {
return SM3.digest(text, 'utf8', 'base64')
}
- 3、使用
import { SM3Digest } from '@/util/sm3Util.js';
const slat = 'xxx'; // 盐,由后端定义,可以从接口获取
const enPw = SM3Digest(this.form.password, slat); // 加密
- 2、前端在请求发送之前使用 国密SM3杂凑(摘要)算法 计算请求参数的哈希值。
要在项目中使用 crypto-js 进行 HMAC-SHA256 加密,首先需要安装 crypto-js 包。
import CryptoJS from 'crypto-js';
// 示例数据和密钥
const data = 'message';
const key = 'secret-key';
// 生成 HMAC-SHA256
const hash = CryptoJS.HmacSHA256(data, key);
// 将哈希转换为字符串
const hashString = hash.toString(CryptoJS.enc.Hex);
console.log(hashString);
- 3、发送者使用自己的私钥和哈希值,通过数字签名算法(如ECDSA或DSA)生成数字签名。
使用 CryptoJS (crypto.js) 進行 HmacSHA256
验证签名
- 1、接收者使用相同的哈希算法计算消息的哈希值。
- 2、接收者使用发送者的公钥对数字签名进行解密。
- 3、如果解密后的哈希值与消息的哈希值匹配,则证明消息未被篡改,且确实来自发送者。这是因为只有发送者知道私钥,能够生成正确的签名。
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.digest.SM3;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* SM3 摘要签名算法工具类
*/
public class SM3Util {
private static Map<String, SM3> sm3Map = new ConcurrentHashMap<>();
/**
* 获取SM3
* @param salt,加盐
* @return SM3
*/
public static SM3 getSm3( String salt) {
return sm3Map.computeIfAbsent(salt, k -> new SM3(salt.getBytes(CharsetUtil.CHARSET_UTF_8)));
}
/**
* SM3-摘要
*/
public static String digest(String salt, String plainTxt) {
SM3 sm3 = getSm3(salt);
return sm3.digestHex(plainTxt);
}
}
方案-3: 前端在传输前对敏感数据进行数字签名
,后端服务进行签名验证
(HMAC 摘要算法)
与请求加解密一样,除了使用
国密SM3杂凑(摘要)算法
,还可以使用HMAC 摘要算法
,进行摘要操作。
- 前端在传输前对 Query 参数 和 Body 进行
HMAC 摘要
,并作为参数传递给后端- 后端服务在 Gateway 再次进行
HMAC 摘要
,并与前端的摘要进行对比
签名过程
- 1、安装 crypto-js 包
npm install crypto-js
- 2、前端在请求发送之前使用哈希算法(如 SHA-256)计算请求参数的哈希值。
import CryptoJS from 'crypto-js';
// 示例数据和密钥
const data = 'message';
const key = 'secret-key';
// 生成 HMAC-SHA256
const hash = CryptoJS.HmacSHA256(data, key);
// 将哈希转换为字符串
const hashString = hash.toString(CryptoJS.enc.Hex);
console.log(hashString);
3、前端使用私钥和哈希值,通过数字签名算法(如ECDSA或DSA)生成数字签名。
RSA (Rivest-Shamir-Adleman)
DSA (Digital Signature Algorithm)
ECDSA (Elliptic Curve Digital Signature Algorithm)
EdDSA (Edwards-curve Digital Signature Algorithm)
HMAC (Hash-based Message Authentication Code)
验证签名
- 1、接收者使用相同的哈希算法计算消息的哈希值。
- 2、接收者使用发送者的公钥对数字签名进行解密。
- 3、如果解密后的哈希值与消息的哈希值匹配,则证明消息未被篡改,且确实来自发送者。这是因为只有发送者知道私钥,能够生成正确的签名。
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.digest.HMac;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* HMAC 摘要签名算法工具类
*/
public class HMACUtil {
private static Map<String, HMac> hMacMap = new ConcurrentHashMap<>();
/**
* 获取 HMac
*
* @param algorithm,摘要算法 HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512
* @param salt,加盐
* @return HMac
*/
public static HMac getHMac( String algorithm, String salt) {
return hMacMap.computeIfAbsent(salt, k -> new HMac(algorithm, salt.getBytes(CharsetUtil.CHARSET_UTF_8)));
}
/**
* HMac-摘要
*/
public static String digest(String algorithm, String salt, String plainTxt) {
HMac hMac = getHMac(algorithm, salt);
return hMac.digestHex(plainTxt);
}
}
作者:Jeebiz 创建时间:2024-11-05 19:30
最后编辑:Jeebiz 更新时间:2024-11-14 21:58
最后编辑:Jeebiz 更新时间:2024-11-14 21:58