新增贷款定价敏感字段加解密服务
This commit is contained in:
@@ -103,3 +103,7 @@ xss:
|
|||||||
security:
|
security:
|
||||||
password-transfer:
|
password-transfer:
|
||||||
key: "1234567890abcdef"
|
key: "1234567890abcdef"
|
||||||
|
|
||||||
|
loan-pricing:
|
||||||
|
sensitive:
|
||||||
|
key: "1234567890abcdef"
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ruoyi.loanpricing.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LoanPricingSensitiveDisplayService
|
||||||
|
{
|
||||||
|
public String maskCustName(String custName)
|
||||||
|
{
|
||||||
|
if (!StringUtils.hasText(custName))
|
||||||
|
{
|
||||||
|
return custName;
|
||||||
|
}
|
||||||
|
if (custName.contains("公司") && custName.length() > 4)
|
||||||
|
{
|
||||||
|
return custName.substring(0, 2) + "*".repeat(custName.length() - 4) + custName.substring(custName.length() - 2);
|
||||||
|
}
|
||||||
|
if (custName.length() == 1)
|
||||||
|
{
|
||||||
|
return custName;
|
||||||
|
}
|
||||||
|
return custName.substring(0, 1) + "*".repeat(custName.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String maskIdNum(String idNum)
|
||||||
|
{
|
||||||
|
if (!StringUtils.hasText(idNum))
|
||||||
|
{
|
||||||
|
return idNum;
|
||||||
|
}
|
||||||
|
if (idNum.startsWith("91") && idNum.length() == 18)
|
||||||
|
{
|
||||||
|
return idNum.substring(0, 2) + "*".repeat(13) + idNum.substring(idNum.length() - 3);
|
||||||
|
}
|
||||||
|
if (idNum.matches("\\d{17}[\\dXx]"))
|
||||||
|
{
|
||||||
|
return idNum.substring(0, 4) + "*".repeat(8) + idNum.substring(idNum.length() - 4);
|
||||||
|
}
|
||||||
|
if (idNum.length() > 5)
|
||||||
|
{
|
||||||
|
return idNum.substring(0, 2) + "*".repeat(idNum.length() - 5) + idNum.substring(idNum.length() - 3);
|
||||||
|
}
|
||||||
|
return "*".repeat(idNum.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.ruoyi.loanpricing.service;
|
||||||
|
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SensitiveFieldCryptoService
|
||||||
|
{
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
public SensitiveFieldCryptoService(@Value("${loan-pricing.sensitive.key:}") String key)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encrypt(String plainText)
|
||||||
|
{
|
||||||
|
validateKey();
|
||||||
|
if (!StringUtils.hasText(plainText))
|
||||||
|
{
|
||||||
|
return plainText;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"));
|
||||||
|
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ServiceException("贷款定价敏感字段加密失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String decrypt(String cipherText)
|
||||||
|
{
|
||||||
|
validateKey();
|
||||||
|
if (!StringUtils.hasText(cipherText))
|
||||||
|
{
|
||||||
|
return cipherText;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"));
|
||||||
|
return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText)), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new ServiceException("贷款定价敏感字段解密失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateKey()
|
||||||
|
{
|
||||||
|
if (!StringUtils.hasText(key))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("loan-pricing.sensitive.key 未配置");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ruoyi.loanpricing.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class LoanPricingSensitiveDisplayServiceTest
|
||||||
|
{
|
||||||
|
private final LoanPricingSensitiveDisplayService displayService = new LoanPricingSensitiveDisplayService();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldMaskPersonalNameAndIdNum()
|
||||||
|
{
|
||||||
|
assertEquals("张*", displayService.maskCustName("张三"));
|
||||||
|
assertEquals("1101********1234", displayService.maskIdNum("110101199001011234"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldMaskCorporateNameAndCreditCode()
|
||||||
|
{
|
||||||
|
assertEquals("测试****公司", displayService.maskCustName("测试科技有限公司"));
|
||||||
|
assertEquals("91*************00X", displayService.maskIdNum("91110000100000000X"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.ruoyi.loanpricing.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class SensitiveFieldCryptoServiceTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
void shouldEncryptAndDecryptCustNameAndIdNum()
|
||||||
|
{
|
||||||
|
SensitiveFieldCryptoService service = new SensitiveFieldCryptoService("1234567890abcdef");
|
||||||
|
|
||||||
|
String nameCipher = service.encrypt("张三");
|
||||||
|
String idNumCipher = service.encrypt("110101199001011234");
|
||||||
|
|
||||||
|
assertNotEquals("张三", nameCipher);
|
||||||
|
assertNotEquals("110101199001011234", idNumCipher);
|
||||||
|
assertEquals("张三", service.decrypt(nameCipher));
|
||||||
|
assertEquals("110101199001011234", service.decrypt(idNumCipher));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectBlankKeyConfiguration()
|
||||||
|
{
|
||||||
|
SensitiveFieldCryptoService service = new SensitiveFieldCryptoService("");
|
||||||
|
|
||||||
|
assertThrows(IllegalStateException.class, () -> service.encrypt("张三"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user