You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
5.7 KiB
Java
103 lines
5.7 KiB
Java
package com.yau.digitalrmb.institutionidentity.application;
|
|
|
|
import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentifierApplication;
|
|
import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentifierRepository;
|
|
import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentityCryptography;
|
|
import com.yau.digitalrmb.shared.api.ErrorCode;
|
|
import com.yau.digitalrmb.shared.exception.BusinessException;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
@Service
|
|
public class InstitutionApplicationVerificationService {
|
|
@Resource
|
|
private InstitutionIdentityCryptography cryptography;
|
|
|
|
@Resource
|
|
private InstitutionKeyService keyService;
|
|
|
|
@Resource
|
|
private InstitutionIdentifierRepository repository;
|
|
|
|
@Resource
|
|
private InstitutionTrainingErrorRecorder errorRecorder;
|
|
|
|
@Transactional
|
|
public InstitutionApplicationVerificationResult verify(long applicationId, String verificationKeyId,
|
|
InstitutionKeySubject subject, String operator) {
|
|
InstitutionIdentifierApplication application = requireApplication(applicationId);
|
|
if (!InstitutionKeyService.BANK_SECOND_KEY.equals(verificationKeyId)) {
|
|
recordAndThrow(application, "WRONG_KEY", "VERIFY", verificationKeyId,
|
|
"验证必须选择商业银行第二密钥的公钥", operator);
|
|
}
|
|
requireStatus(application, InstitutionIdentifierApplication.Status.PACKAGED,
|
|
"当前步骤不是央行验证,不能操作", operator);
|
|
InstitutionIdentifierApplication.Status expectedStatus = application.getStatus();
|
|
String originalText = application.getBankCode() + "|" + application.getTimestamp();
|
|
String recalculatedDigest = cryptography.sm3(originalText);
|
|
boolean signatureValid = keyService.verifyCommercialBank(subject, application.getDigest(),
|
|
application.getBankSignature());
|
|
boolean digestMatches = recalculatedDigest.equalsIgnoreCase(application.getDigest());
|
|
invokeDomain(() -> application.recordVerification(verificationKeyId, signatureValid, digestMatches));
|
|
repository.update(application, expectedStatus, "VERIFY",
|
|
signatureValid && digestMatches ? "SM2身份验证和SM3完整性验证通过" : "申请验证失败",
|
|
operator);
|
|
return new InstitutionApplicationVerificationResult(applicationId, application.getStatus().name(),
|
|
"SM2_WITH_SM3_VERIFY_AND_SM3_RECALCULATE", verificationKeyId, originalText,
|
|
application.getDigest(), recalculatedDigest, signatureValid, digestMatches);
|
|
}
|
|
|
|
@Transactional
|
|
public InstitutionIdentifierConfirmationResult confirm(long applicationId, String signingKeyId,
|
|
InstitutionKeySubject subject, String operator) {
|
|
InstitutionIdentifierApplication application = requireApplication(applicationId);
|
|
if (!InstitutionKeyService.CENTRAL_FIRST_KEY.equals(signingKeyId)) {
|
|
recordAndThrow(application, "WRONG_KEY", "CONFIRM", signingKeyId,
|
|
"签名确权必须选择中央银行第一密钥", operator);
|
|
}
|
|
requireStatus(application, InstitutionIdentifierApplication.Status.VERIFIED,
|
|
"申请尚未验证通过,不能进行央行签名确权", operator);
|
|
InstitutionIdentifierApplication.Status expectedStatus = application.getStatus();
|
|
String digest = application.getDigest();
|
|
String identifier = "ORG_" + digest.substring(0, 12);
|
|
String centralBankSignature = keyService.signCentralBank(subject, digest);
|
|
invokeDomain(() -> application.issue(signingKeyId, identifier, centralBankSignature));
|
|
repository.update(application, expectedStatus, "CONFIRM",
|
|
"中央银行第一私钥完成SM2签名确权并签发机构标识", operator);
|
|
return new InstitutionIdentifierConfirmationResult(applicationId, application.getStatus().name(),
|
|
signingKeyId, centralBankSignature, identifier, digest);
|
|
}
|
|
|
|
private InstitutionIdentifierApplication requireApplication(long applicationId) {
|
|
return repository.findById(applicationId).orElseThrow(() ->
|
|
new BusinessException(ErrorCode.RESOURCE_NOT_FOUND, "机构标识申请不存在"));
|
|
}
|
|
|
|
private void requireStatus(InstitutionIdentifierApplication application,
|
|
InstitutionIdentifierApplication.Status expectedStatus,
|
|
String message, String operator) {
|
|
if (application.getStatus() != expectedStatus) {
|
|
recordAndThrow(application, "INVALID_STEP", expectedStatus.name(), null,
|
|
message + ",当前状态:" + application.getStatus().name(), operator);
|
|
}
|
|
}
|
|
|
|
private void recordAndThrow(InstitutionIdentifierApplication application, String errorType, String operationStep,
|
|
String providedKeyId, String message, String operator) {
|
|
int errorSequence = errorRecorder.record(application.getId(), errorType, operationStep, providedKeyId,
|
|
message, operator);
|
|
throw new BusinessException(ErrorCode.VALIDATION_ERROR,
|
|
message + ",本次实训第" + errorSequence + "次错误");
|
|
}
|
|
|
|
private static void invokeDomain(Runnable operation) {
|
|
try {
|
|
operation.run();
|
|
} catch (IllegalArgumentException | IllegalStateException exception) {
|
|
throw new BusinessException(ErrorCode.VALIDATION_ERROR, exception.getMessage());
|
|
}
|
|
}
|
|
}
|