1.添加手机号和身份证的安全性和保密性

2.添加对应的定时任务
This commit is contained in:
sh
2026-03-19 17:26:28 +08:00
parent e61cdafa9d
commit bbb106489e
40 changed files with 1321 additions and 52 deletions

View File

@@ -97,6 +97,9 @@ public class StringUtil {
*/
public static final Map<String, String> REGION_CODE_CODE_MAP;
//批量条数
public static final int BATCH_SIZE = 1000;
static {
Map<String, String> tempMap = new HashMap<>();
tempMap.put("中专及以上", "1");
@@ -365,4 +368,13 @@ public class StringUtil {
default: return code;
}
}
public static <T> List<List<T>> splitList(List<T> list, int batchSize) {
List<List<T>> batches = new ArrayList<>();
for (int i = 0; i < list.size(); i += batchSize) {
int end = Math.min(i + batchSize, list.size());
batches.add(list.subList(i, end));
}
return batches;
}
}

View File

@@ -0,0 +1,587 @@
package com.ruoyi.cms.util.encrypt;
import com.ruoyi.cms.domain.CommunityUser;
import com.ruoyi.cms.domain.EmployeeConfirm;
import com.ruoyi.cms.domain.JobContact;
import com.ruoyi.cms.domain.vo.CandidateVO;
import com.ruoyi.cms.domain.vo.WechatGroupVo;
import com.ruoyi.cms.util.StringUtil;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.entity.Company;
import com.ruoyi.common.core.domain.entity.CompanyContact;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.EncryptDecryptUtil;
import org.apache.commons.lang3.StringUtils;
import org.quickssl.api.CryptoClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
/**
* 加密验签工具类
*/
@Component
public class QuickValidUtils {
private static final Logger log = LoggerFactory.getLogger(QuickValidUtils.class);
private static volatile QuickValidUtils INSTANCE;
@Autowired
private EncryptDecryptUtil encryptDecryptUtil;
private static final String TAMPER_PHONE_IDCARD_MSG = "手机号或者身份证信息完整性已被篡改,请联系管理员确认!";
private static final String TAMPER_PHONE_MSG = "手机号信息完整性已被篡改,请联系管理员确定!";
private static final String TAMPER_IDCARD_MSG = "身份证信息完整性已被篡改,请联系管理员确定!";
/**
* Spring初始化完成后赋值静态实例
*/
@PostConstruct
public synchronized void init() {
if (INSTANCE != null) {
log.warn("QuickValidUtils已初始化重复初始化被忽略");
return;
}
if (encryptDecryptUtil == null) {
throw new IllegalStateException("EncryptDecryptUtil注入失败请检查Spring配置");
}
INSTANCE = this;
log.info("QuickValidUtils初始化成功");
}
/**
* 获取工具类实例
*/
private static QuickValidUtils getInstance() {
if (INSTANCE == null) {
synchronized (QuickValidUtils.class) {
if (INSTANCE == null) {
throw new IllegalStateException("QuickValidUtils未初始化请确保Spring容器已启动并完成注入");
}
}
}
return INSTANCE;
}
// ======================== 提取的通用私有方法 ========================
/**
* 通用SM4解密方法
* @param cipherText 加密串
* @return 解密后的明文
* @throws CryptoClient.CryptoException 解密异常
*/
private static String sm4Decrypt(String cipherText) throws CryptoClient.CryptoException {
return getInstance().encryptDecryptUtil.sm4Decrypt(cipherText);
}
/**
* 通用SM4加密方法
* @param plainText 明文
* @return 加密后的密文
* @throws CryptoClient.CryptoException 加密异常
*/
private static String sm4Encrypt(String plainText) throws CryptoClient.CryptoException {
return getInstance().encryptDecryptUtil.sm4Encrypt(plainText);
}
/**
* 通用SM3验签方法
* @param plainText 明文
* @param sign 待验证的签名字符串
* @return true-验签通过false-验签失败
* @throws Exception 验签异常
*/
private static boolean sm3Verify(String plainText, String sign) throws CryptoClient.CryptoException {
return getInstance().encryptDecryptUtil.sm3Verify(plainText, sign);
}
/**
* 通用SM3哈希方法生成签名字符串
* @param plainText 明文
* @return 哈希后的签名字符串
* @throws CryptoClient.CryptoException 哈希异常
*/
private static String sm3Hash(String plainText) throws CryptoClient.CryptoException {
return getInstance().encryptDecryptUtil.sm3Hash(plainText);
}
// ======================== 原有业务方法 ========================
/**
* 企业-解密手机号/身份证并验签
* @param company 企业实体
*/
public static void legalPhoneOrIdCardValid(Company company) {
String phone = "";
boolean phoneTrue = true;
String idCard = "";
boolean idCardTrue = true;
try {
if (!StringUtils.isBlank(company.getLegalPhone())) {
phone = sm4Decrypt(company.getLegalPhoneEncrypt());
phoneTrue = sm3Verify(phone, company.getLegalPhoneCipher());
//company.setLegalPhone(phone);
}
if (!StringUtils.isBlank(company.getLegalIdCard())) {
idCard = sm4Decrypt(company.getLegalIdCardEncrypt());
idCardTrue = sm3Verify(idCard, company.getLegalIdCardCipher());
//company.setLegalIdCard(idCard);
}
if (!phoneTrue || !idCardTrue) {
throw new RuntimeException(TAMPER_PHONE_IDCARD_MSG);
}
} catch (CryptoClient.CryptoException e) {
log.error("企业法人手机号/身份证解密失败", e);
throw new RuntimeException("解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("企业法人手机号/身份证验签失败", e1);
throw new RuntimeException("验签失败:" + e1.getMessage(), e1);
}
}
/**
* 企业或个人
* @param vo
*/
public static void candidatePhoneOrIdCardValid(CandidateVO vo) {
String phone = "";
boolean phoneTrue = true;
String idCard = "";
boolean idCardTrue = true;
try {
if(!StringUtils.isBlank(vo.getPhone())){
phone=sm4Decrypt(vo.getPhoneEncrypt());
phoneTrue=sm3Verify(phone,vo.getPhoneCipher());
//vo.setPhone(phone);
}
if(!StringUtils.isBlank(vo.getIdCard())){
idCard=sm4Decrypt(vo.getIdCardEncrypt());
idCardTrue=sm3Verify(idCard,vo.getIdCardCipher());
//vo.setIdCard(idCard);
}
if (!phoneTrue || !idCardTrue) {
throw new RuntimeException(TAMPER_PHONE_IDCARD_MSG);
}
} catch (CryptoClient.CryptoException e) {
log.error("企业和个人手机号/身份证解密失败", e);
throw new RuntimeException("解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("企业和个人手机号/身份证验签失败", e1);
throw new RuntimeException("验签失败:" + e1.getMessage(), e1);
}
}
/**
* 企业联系人手机号解密/完整性验签
* @param contact 企业联系人实体
*/
public static void companyContactPhoneValid(CompanyContact contact) {
String phone = "";
boolean phoneTrue = true;
try {
if (!StringUtils.isBlank(contact.getContactPersonPhone())) {
phone = sm4Decrypt(contact.getContactPersonPhoneEncrypt());
phoneTrue = sm3Verify(phone, contact.getContactPersonPhoneCipher());
//contact.setContactPersonPhone(phone);
if (!phoneTrue) {
throw new RuntimeException(TAMPER_PHONE_MSG);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("企业联系人手机号解密失败", e);
throw new RuntimeException("用户信息解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("企业联系人手机号验签失败", e1);
throw new RuntimeException("用户信息验证失败:" + e1.getMessage(), e1);
}
}
/**
* 用户验证-手机号解密/验证完整性
* @param appUser 用户实体
*/
public static void phoneValid(AppUser appUser) {
String phone = "";
boolean phoneTrue = false;
try {
if(StringUtils.isNotBlank(appUser.getPhoneEncrypt())) {
phone = sm4Decrypt(appUser.getPhoneEncrypt());
phoneTrue = sm3Verify(phone, appUser.getPhoneCipher());
//appUser.setPhone(phone);
if (!phoneTrue) {
throw new RuntimeException(TAMPER_PHONE_MSG);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("App用户手机号解密失败", e);
throw new RuntimeException("用户信息解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("App用户手机号验签失败", e1);
throw new RuntimeException("用户信息验证失败:" + e1.getMessage(), e1);
}
}
/**
* 岗位联系人解密/验证完整性
* @param jobContact
*/
public static void phoneValid(JobContact jobContact) {
String phone = "";
boolean phoneTrue = false;
try {
if(StringUtils.isNotBlank(jobContact.getContactPersonPhoneEncrypt())){
phone=sm4Decrypt(jobContact.getContactPersonPhoneEncrypt());
phoneTrue=sm3Verify(phone,jobContact.getContactPersonPhoneCipher());
//jobContact.setContactPersonPhone(phone);
if (!phoneTrue) {
throw new RuntimeException(TAMPER_PHONE_MSG);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("岗位联系人手机号解密失败", e);
throw new RuntimeException("用户信息解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("岗位联系人手机号验签失败", e1);
throw new RuntimeException("用户信息验证失败:" + e1.getMessage(), e1);
}
}
/**
* 工作人员手机号解密/验证完整性
* @param communityUser
*/
public static void phoneValid(CommunityUser communityUser) {
String phone = "";
boolean phoneTrue = false;
try {
if(StringUtils.isNotBlank(communityUser.getPhoneNumber())){
phone=sm4Decrypt(communityUser.getPhoneNumberEncrypt());
phoneTrue=sm3Verify(phone,communityUser.getPhoneNumberCipher());
//communityUser.setPhoneNumber(phone);
if (!phoneTrue) {
throw new RuntimeException(TAMPER_PHONE_MSG);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("手机号解密失败", e);
throw new RuntimeException("手机号解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("手机号验签失败", e1);
throw new RuntimeException("手机号验证失败:" + e1.getMessage(), e1);
}
}
/**
*转发对象手机号
* @param vo
*/
public static void phoneValid(WechatGroupVo vo) {
String phone = "";
boolean phoneTrue = false;
try {
if(StringUtils.isNotBlank(vo.getPhoneNumber())){
phone=sm4Decrypt(vo.getPhoneNumberEncrypt());
phoneTrue=sm3Verify(phone,vo.getPhoneNumberCipher());
//vo.setPhoneNumber(phone);
if (!phoneTrue) {
throw new RuntimeException(TAMPER_PHONE_MSG);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("手机号解密失败", e);
throw new RuntimeException("手机号解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("手机号验签失败", e1);
throw new RuntimeException("手机号验证失败:" + e1.getMessage(), e1);
}
}
/**
* 身份证解密/验证完整性
* @param appUser 用户实体
*/
public static void idCardValid(AppUser appUser) {
String idCard = "";
boolean idCardTrue = true;
try {
if (StringUtils.isNotBlank(appUser.getIdCardCipher())) {
idCard = sm4Decrypt(appUser.getIdCardEncrypt());
idCardTrue = sm3Verify(idCard, appUser.getIdCardCipher());
//appUser.setIdCard(idCard);
}
if (!idCardTrue) {
throw new RuntimeException(TAMPER_IDCARD_MSG);
}
} catch (CryptoClient.CryptoException e) {
log.error("App用户身份证解密失败", e);
throw new RuntimeException("用户信息解密失败:" + e.getMessage(), e);
} catch (Exception e1) {
log.error("App用户身份证验签失败", e1);
throw new RuntimeException("用户信息验证失败:" + e1.getMessage(), e1);
}
}
/**
* 手机号加密/生成完整性校验串
* @param appUser 用户实体
*/
public static void savePhoneSm4(AppUser appUser) {
try {
String phoneSm4 = sm4Encrypt(appUser.getPhone());
String phoneSm3 = sm3Hash(appUser.getPhone());
appUser.setPhoneEncrypt(phoneSm4);
appUser.setPhoneCipher(phoneSm3);
} catch (CryptoClient.CryptoException e) {
log.error("App用户手机号加密失败", e);
throw new RuntimeException("手机号加密失败", e);
}
}
/**
* 岗位联系人加密
* @param jobContact
*/
public static void savePhoneSm4(JobContact jobContact) {
try {
if(!StringUtils.isBlank(jobContact.getContactPersonPhone())){
String phoneSm4=sm4Encrypt(jobContact.getContactPersonPhone());
String phoneSm3=sm3Hash(jobContact.getContactPersonPhone());
jobContact.setContactPersonPhoneEncrypt(phoneSm4);
jobContact.setContactPersonPhoneCipher(phoneSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("岗位联系人用户手机号加密失败", e);
throw new RuntimeException("手机号加密失败", e);
}
}
/**
* 微信抓取负责人
* @param communityUser
*/
public static void savePhoneSm4(CommunityUser communityUser) {
try {
if(!StringUtils.isBlank(communityUser.getPhoneNumber())){
String phoneSm4=sm4Encrypt(communityUser.getPhoneNumber());
String phoneSm3=sm3Hash(communityUser.getPhoneNumber());
communityUser.setPhoneNumberEncrypt(phoneSm4);
communityUser.setPhoneNumberCipher(phoneSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("岗位联系人用户手机号加密失败", e);
throw new RuntimeException("手机号加密失败", e);
}
}
/**
* 身份证加密/生成完整性校验串
* @param appUser 用户实体
*/
public static void saveIdCardSm4(AppUser appUser) {
try {
if (!StringUtils.isBlank(appUser.getIdCard())) {
String idCardUper = StringUtil.toUpperCaseIgnoreBlank(appUser.getIdCard());
String idCardSm4 = sm4Encrypt(idCardUper);
String idCardSm3 = sm3Hash(idCardUper);
appUser.setIdCardEncrypt(idCardSm4);
appUser.setIdCardCipher(idCardSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("App用户身份证加密失败", e);
throw new RuntimeException("身份证加密失败", e);
}
}
/**
* 手机号、身份证加密/生成完整性校验串
* @param appUser 用户实体
*/
public static void savePhoneIdCardSm4(AppUser appUser) {
try {
//密码机完整性/保密性
if (!StringUtils.isBlank(appUser.getPhone())) {
String phoneSm4 = sm4Encrypt(appUser.getPhone());
String phoneSm3 = sm3Hash(appUser.getPhone());
appUser.setPhoneEncrypt(phoneSm4);
appUser.setPhoneCipher(phoneSm3);
}
if (!StringUtils.isBlank(appUser.getIdCard())) {
String idCardUper = StringUtil.toUpperCaseIgnoreBlank(appUser.getIdCard());
String idCardSm4 = sm4Encrypt(idCardUper);
String idCardSm3 = sm3Hash(idCardUper);
appUser.setIdCardEncrypt(idCardSm4);
appUser.setIdCardCipher(idCardSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("App用户手机号+身份证加密失败", e);
}
}
/**
* 身份证手机号加密/完整性
* @param employeeConfirm
*/
public static void savePhoneIdCardSm4(EmployeeConfirm employeeConfirm){
try {
if(!StringUtils.isBlank(employeeConfirm.getContactPersonPhone())){
String phoneSm4=sm4Encrypt(employeeConfirm.getContactPersonPhone());
String phoneSm3=sm3Hash(employeeConfirm.getContactPersonPhone());
employeeConfirm.setContactPersonPhoneEncrypt(phoneSm4);
employeeConfirm.setContactPersonPhoneCipher(phoneSm3);
}
if(!StringUtils.isBlank(employeeConfirm.getIdCard())){
String idCardSm4=sm4Encrypt(employeeConfirm.getIdCard());
String idCardSm3=sm3Hash(employeeConfirm.getIdCard());
employeeConfirm.setIdCardEncrypt(idCardSm4);
employeeConfirm.setIdCardCipher(idCardSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("企业法人手机号/身份证加密失败", e);
throw new RuntimeException("手机号加密失败", e);
}
}
/**
* 企业法人身份证和手机号加密/生成完整性校验串
* @param company 企业实体
*/
public static void legalSm4(Company company) {
String legalIdCard = company.getLegalIdCard();
String legalPhone = company.getLegalPhone();
try {
if (!StringUtils.isBlank(legalPhone)) {
String phoneSm4 = sm4Encrypt(legalPhone);
String phoneSm3 = sm3Hash(legalPhone);
company.setLegalPhoneEncrypt(phoneSm4);
company.setLegalPhoneCipher(phoneSm3);
}
if (!StringUtils.isBlank(legalIdCard)) {
String idCardSm4 = sm4Encrypt(legalIdCard);
String idCardSm3 = sm3Hash(legalIdCard);
company.setLegalIdCardEncrypt(idCardSm4);
company.setLegalIdCardCipher(idCardSm3);
}
} catch (CryptoClient.CryptoException e) {
log.error("企业法人手机号/身份证加密失败", e);
throw new RuntimeException("法人手机号/身份证,加密失败", e);
}
}
/**
* 企业联系人手机号加密/生成完整性校验串
* @param contact 企业联系人实体
*/
public static void saveCompanyContactPhoneSm4(CompanyContact contact) {
try {
String phoneSm4 = sm4Encrypt(contact.getContactPersonPhone());
String phoneSm3 = sm3Hash(contact.getContactPersonPhone());
contact.setContactPersonPhoneEncrypt(phoneSm4);
contact.setContactPersonPhoneCipher(phoneSm3);
} catch (CryptoClient.CryptoException e) {
log.error("企业联系人手机号加密失败", e);
throw new RuntimeException("手机号加密失败", e);
}
}
/**
* 加密系统管理用户
* @param sysUser
*/
public static void saveSysUserSm4(SysUser sysUser) {
String phone = sysUser.getPhonenumber();
String idCard = sysUser.getIdCard();
try {
if (!StringUtils.isBlank(phone)) {
String phoneSm4 = sm4Encrypt(phone);
String phoneSm3 = sm3Hash(phone);
sysUser.setPhonenumberEncrypt(phoneSm4);
sysUser.setPhonenumberCipher(phoneSm3);
}
Long[] roleIds=sysUser.getRoleIds();
if (!StringUtils.isBlank(idCard)&& roleIds != null && roleIds.length > 0) {
boolean contains1102 = !Arrays.asList(roleIds).contains(StringUtil.COMPANY_ADMIN_ROLE_KEY);
if (contains1102) {
String idCardSm4 = sm4Encrypt(idCard);
String idCardSm3 = sm3Hash(idCard);
sysUser.setIdCardEncrypt(idCardSm4);
sysUser.setIdCardCipher(idCardSm3);
}
}
} catch (CryptoClient.CryptoException e) {
log.error("企业法人手机号/身份证加密失败", e);
throw new RuntimeException("法人手机号/身份证,加密失败", e);
}
}
/**
* 通用SM4解密方法对外提供
* @param sm4 加密串
* @return 解密后的明文
*/
public static String getSm4Decrypt(String sm4) {
String deSm4 = "";
try {
deSm4 = sm4Decrypt(sm4);
} catch (CryptoClient.CryptoException e) {
deSm4=sm4;
log.error("通用SM4解密失败密文{}", sm4, e);
}
return deSm4;
}
/**
* 加密
* @param sm4
* @return
*/
public static String getSm4Encrypt(String sm4) {
String deSm4 = "";
try {
deSm4 = sm4Encrypt(sm4);
} catch (CryptoClient.CryptoException e) {
deSm4=sm4;
log.error("通用SM4加密失败密文{}", sm4, e);
}
return deSm4;
}
/**
* pc互联网端-加密返回数组
* @param phone
* @return
*/
public static String[] savePhoneSm4(String phone){
String phoneSm4;
String phoneSm3;
try {
phoneSm4 = sm4Encrypt(phone);
phoneSm3= sm3Hash(phone);
} catch (CryptoClient.CryptoException e) {
log.error("用户手机号加密失败:{}",phone, e);
throw new RuntimeException("手机号加密失败",e);
}
return new String[]{phoneSm4,phoneSm3};
}
/**
* pc互联网端-用户身份证加密
* @param idCard
* @return
*/
public static String[] saveIdCardSm4(String idCard){
String idCardSm4;
String idCardSm3;
try {
idCardSm4 = sm4Encrypt(idCard);
idCardSm3= sm3Hash(idCard);
} catch (CryptoClient.CryptoException e) {
log.error("用户身份证加密失败:{}",idCard, e);
throw new RuntimeException("身份证加密失败",e);
}
return new String[]{idCardSm4,idCardSm3};
}
}