|
|
|
|
@ -151,15 +151,14 @@ public class RemoteWalletService {
|
|
|
|
|
}
|
|
|
|
|
String trimmedPrivateKey = providedPrivateKey.trim();
|
|
|
|
|
|
|
|
|
|
// 检查数据库中是否已存在企业法人私钥(按远程开立法人姓名过滤,避免取到张三等其他法人的私钥)
|
|
|
|
|
String legalPersonName = app.getLegalPerson() != null ? app.getLegalPerson() : "李四";
|
|
|
|
|
// 检查数据库中是否已存在企业法人私钥
|
|
|
|
|
String legalPersonName = app.getLegalPerson() != null ? app.getLegalPerson() : "企业法人";
|
|
|
|
|
CorporateWalletKeyInfoEntity existingKey = keyInfoMapper.selectOne(
|
|
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CorporateWalletKeyInfoEntity>()
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getUserId, subject.getUserId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getSchoolId, subject.getSchoolId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getClassId, subject.getClassId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getKeyType, LEGAL_PERSON_KEY_TYPE)
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getHolder, legalPersonName)
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getIsPrivateKey, true)
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getDeleted, false)
|
|
|
|
|
.orderByDesc(CorporateWalletKeyInfoEntity::getCreatedAt)
|
|
|
|
|
@ -363,66 +362,13 @@ public class RemoteWalletService {
|
|
|
|
|
results.add(buildKeyResult("商业银行第二公钥", "中国银行",
|
|
|
|
|
bankKey.getPublicKey(), false, "REUSED"));
|
|
|
|
|
|
|
|
|
|
// 3. 企业法人密钥
|
|
|
|
|
// 原型要求固定持有方名册:临柜法人(如张三)与远程法人(如李四)都必须有"私钥+公钥"一对,
|
|
|
|
|
// 缺失的按需生成后加入列表;同一法人只输出最新一对。
|
|
|
|
|
// 3. 企业法人密钥(按需生成)
|
|
|
|
|
RemoteWalletApplication app = findOrCreate(subject);
|
|
|
|
|
String remoteLegalPerson = app.getLegalPerson() != null ? app.getLegalPerson() : "李四";
|
|
|
|
|
com.yau.digitalrmb.corporatewallet.domain.CorporateWalletApplication counterApp = corporateRepository
|
|
|
|
|
.findLatest(subject.getUserId(), subject.getSchoolId(), subject.getClassId())
|
|
|
|
|
.orElse(null);
|
|
|
|
|
String counterLegalPerson = counterApp != null && counterApp.getLegalPerson() != null
|
|
|
|
|
? counterApp.getLegalPerson() : "张三";
|
|
|
|
|
String counterCorpName = counterApp != null && counterApp.getCorpName() != null
|
|
|
|
|
? counterApp.getCorpName() : "创新科技公司";
|
|
|
|
|
|
|
|
|
|
// 3a. 查出已有企业法人私钥,按法人姓名(剥离企业名后缀)去重,保留每人最新一条
|
|
|
|
|
java.util.List<CorporateWalletKeyInfoEntity> existingLegalPersonKeys = keyInfoMapper.selectList(
|
|
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CorporateWalletKeyInfoEntity>()
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getUserId, subject.getUserId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getSchoolId, subject.getSchoolId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getClassId, subject.getClassId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getKeyType, "企业法人私钥")
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getDeleted, false)
|
|
|
|
|
.orderByDesc(CorporateWalletKeyInfoEntity::getCreatedAt));
|
|
|
|
|
java.util.Map<String, CorporateWalletKeyInfoEntity> latestKeyByPerson = new java.util.LinkedHashMap<>();
|
|
|
|
|
for (CorporateWalletKeyInfoEntity existing : existingLegalPersonKeys) {
|
|
|
|
|
latestKeyByPerson.putIfAbsent(personName(existing.getHolder()), existing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3b. 临柜法人(如张三(创新科技公司)):已有则复用(公钥缺失则推导补齐),没有则新生成一对
|
|
|
|
|
String counterPrivate;
|
|
|
|
|
String counterPublic;
|
|
|
|
|
CorporateWalletKeyInfoEntity counterExisting = latestKeyByPerson.get(counterLegalPerson);
|
|
|
|
|
if (counterExisting != null) {
|
|
|
|
|
counterPrivate = counterExisting.getKeyValue();
|
|
|
|
|
counterPublic = findOrDerivePublicKey(subject, counterExisting);
|
|
|
|
|
} else {
|
|
|
|
|
String[] pair = getOrCreateKeyPair(subject, "企业法人私钥", "企业法人公钥", counterLegalPerson);
|
|
|
|
|
counterPrivate = pair[0];
|
|
|
|
|
counterPublic = pair[1];
|
|
|
|
|
}
|
|
|
|
|
results.add(buildKeyResult("企业法人私钥", displayHolder(counterLegalPerson, counterCorpName),
|
|
|
|
|
counterPrivate, true, counterExisting != null ? "REUSED" : "NEW"));
|
|
|
|
|
results.add(buildKeyResult("企业法人公钥", displayHolder(counterLegalPerson, counterCorpName),
|
|
|
|
|
counterPublic, false, counterExisting != null ? "REUSED" : "NEW"));
|
|
|
|
|
|
|
|
|
|
// 3c. 远程法人(如李四(企业名称)):已有则复用,没有则新生成一对;与临柜法人同名时只输出一对
|
|
|
|
|
String remotePrivate;
|
|
|
|
|
String remotePublic;
|
|
|
|
|
CorporateWalletKeyInfoEntity remoteExisting = latestKeyByPerson.get(remoteLegalPerson);
|
|
|
|
|
if (remoteLegalPerson.equals(counterLegalPerson)) {
|
|
|
|
|
remotePrivate = counterPrivate;
|
|
|
|
|
remotePublic = counterPublic;
|
|
|
|
|
} else if (remoteExisting != null) {
|
|
|
|
|
remotePrivate = remoteExisting.getKeyValue();
|
|
|
|
|
remotePublic = findOrDerivePublicKey(subject, remoteExisting);
|
|
|
|
|
} else {
|
|
|
|
|
String[] pair = getOrCreateKeyPair(subject, "企业法人私钥", "企业法人公钥", remoteLegalPerson);
|
|
|
|
|
remotePrivate = pair[0];
|
|
|
|
|
remotePublic = pair[1];
|
|
|
|
|
}
|
|
|
|
|
String remoteDisplayHolder = displayHolder(remoteLegalPerson, app.getCorpName());
|
|
|
|
|
String legalPersonName = app.getLegalPerson() != null ? app.getLegalPerson() : "企业法人";
|
|
|
|
|
String[] legalPersonPair = getOrCreateKeyPair(subject, "企业法人私钥", "企业法人公钥",
|
|
|
|
|
legalPersonName);
|
|
|
|
|
results.add(buildKeyResult("企业法人私钥", legalPersonName, legalPersonPair[0], true, "NEW"));
|
|
|
|
|
results.add(buildKeyResult("企业法人公钥", legalPersonName, legalPersonPair[1], false, "NEW"));
|
|
|
|
|
|
|
|
|
|
// 4. 数币操作员密钥(按需生成)
|
|
|
|
|
String[] operatorPair = getOrCreateKeyPair(subject, "数币操作员私钥", "数币操作员公钥",
|
|
|
|
|
@ -436,12 +382,6 @@ public class RemoteWalletService {
|
|
|
|
|
results.add(buildKeyResult("数币复核员私钥", "赵六", reviewerPair[0], true, "NEW"));
|
|
|
|
|
results.add(buildKeyResult("数币复核员公钥", "赵六", reviewerPair[1], false, "NEW"));
|
|
|
|
|
|
|
|
|
|
// 5b. 远程法人密钥对按原型顺序插入:位于数币复核员之后、监管机构之前
|
|
|
|
|
results.add(buildKeyResult("企业法人私钥", remoteDisplayHolder,
|
|
|
|
|
remotePrivate, true, remoteExisting != null ? "REUSED" : "NEW"));
|
|
|
|
|
results.add(buildKeyResult("企业法人公钥", remoteDisplayHolder,
|
|
|
|
|
remotePublic, false, remoteExisting != null ? "REUSED" : "NEW"));
|
|
|
|
|
|
|
|
|
|
// 6. 监管机构密钥(按需生成)
|
|
|
|
|
String[] regulatorPair = getOrCreateKeyPair(subject, "监管机构私钥", "监管机构公钥",
|
|
|
|
|
"民政部公益监管中心");
|
|
|
|
|
@ -462,58 +402,11 @@ public class RemoteWalletService {
|
|
|
|
|
return new String[]{privateKey, publicKey};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 读取指定法人已有私钥对应的公钥:库中存在则返回;缺失时从私钥推导并落库,保证公钥私钥成对。
|
|
|
|
|
*/
|
|
|
|
|
private String findOrDerivePublicKey(InstitutionKeySubject subject, CorporateWalletKeyInfoEntity privateKeyEntity) {
|
|
|
|
|
CorporateWalletKeyInfoEntity existingPub = keyInfoMapper.selectOne(
|
|
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CorporateWalletKeyInfoEntity>()
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getUserId, subject.getUserId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getSchoolId, subject.getSchoolId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getClassId, subject.getClassId())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getKeyType, "企业法人公钥")
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getHolder, privateKeyEntity.getHolder())
|
|
|
|
|
.eq(CorporateWalletKeyInfoEntity::getDeleted, false)
|
|
|
|
|
.orderByDesc(CorporateWalletKeyInfoEntity::getCreatedAt)
|
|
|
|
|
.last("LIMIT 1"));
|
|
|
|
|
if (existingPub != null && existingPub.getKeyValue() != null && !existingPub.getKeyValue().trim().isEmpty()) {
|
|
|
|
|
return existingPub.getKeyValue();
|
|
|
|
|
}
|
|
|
|
|
String derived = cryptography.derivePublicKey(privateKeyEntity.getKeyValue());
|
|
|
|
|
saveKeyInfo(subject, "企业法人公钥", privateKeyEntity.getHolder(), derived, false, "NEW");
|
|
|
|
|
return derived;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private RemoteWalletKeyResult buildKeyResult(String keyType, String holder, String keyValue,
|
|
|
|
|
boolean isPrivateKey, String source) {
|
|
|
|
|
return new RemoteWalletKeyResult(keyType, holder, "SM2", keyValue, isPrivateKey, source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从持有方名称中提取法人姓名:兼容“张三”“张三(创新科技公司)”两种存储格式。
|
|
|
|
|
*/
|
|
|
|
|
private String personName(String holder) {
|
|
|
|
|
if (holder == null || holder.trim().isEmpty()) {
|
|
|
|
|
return "企业法人";
|
|
|
|
|
}
|
|
|
|
|
String trimmed = holder.trim();
|
|
|
|
|
int idx = trimmed.indexOf('(');
|
|
|
|
|
if (idx < 0) {
|
|
|
|
|
idx = trimmed.indexOf('(');
|
|
|
|
|
}
|
|
|
|
|
return idx > 0 ? trimmed.substring(0, idx).trim() : trimmed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 持有方展示名:法人姓名(企业名称),如“张三(创新科技公司)”;无企业名时仅返回姓名。
|
|
|
|
|
*/
|
|
|
|
|
private String displayHolder(String person, String corpName) {
|
|
|
|
|
if (corpName == null || corpName.trim().isEmpty()) {
|
|
|
|
|
return person;
|
|
|
|
|
}
|
|
|
|
|
return person + "(" + corpName.trim() + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校验远程开立和临柜开立的企业信息一致性
|
|
|
|
|
* @param remoteApp 远程开立申请
|
|
|
|
|
|