莫名奇妙的验签成功
This commit is contained in:
parent
72eff5f4a4
commit
5a2c94a32c
@ -314,6 +314,11 @@ public class CMSUtil {
|
||||
System.out.println("\n 处理第 " + (si+1) + " 个 SignerInfo...");
|
||||
ASN1Encodable signerInfoEncodable = signerInfosSet.getObjectAt(si);
|
||||
ASN1Primitive signerInfoPrim = signerInfoEncodable.toASN1Primitive();
|
||||
|
||||
byte[] signerInfoDer = signerInfoPrim.getEncoded(ASN1Encoding.DER);
|
||||
System.out.println(" SignerInfo DER 编码长度: " + signerInfoDer.length + " bytes");
|
||||
System.out.println(" SignerInfo DER 编码: " + bytesToHex(signerInfoDer));
|
||||
|
||||
System.out.println(" SignerInfo 原始类型: " + signerInfoPrim.getClass().getSimpleName());
|
||||
|
||||
String signerInfoPrimClassName = signerInfoPrim.getClass().getName();
|
||||
@ -487,40 +492,31 @@ public class CMSUtil {
|
||||
System.out.println(" 签名值 (Hex): " + bytesToHex(signatureValue));
|
||||
System.out.println(" signedAttrs 数据类型: " + authAttrsData.getClass().getName());
|
||||
|
||||
String[] algNames = {"SM3withSM2", "SHA256withSM2", "SM2"};
|
||||
byte[] signingData = signedAttrsEncoded;
|
||||
boolean valid = false;
|
||||
for (String algName : algNames) {
|
||||
try {
|
||||
Signature signature = Signature.getInstance(algName, "BC");
|
||||
signature.initVerify(signerCert.getPublicKey());
|
||||
signature.update(signedAttrsEncoded);
|
||||
valid = signature.verify(signatureValue);
|
||||
System.out.println(" 算法 " + algName + " 验签结果: " + (valid ? "成功" : "失败"));
|
||||
if (valid) break;
|
||||
} catch (Exception e) {
|
||||
System.out.println(" 算法 " + algName + " 失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
System.out.println("\n [调试] 尝试使用原始签名值格式验签...");
|
||||
try {
|
||||
Signature signature = Signature.getInstance("SM3withSM2", "BC");
|
||||
signature.initVerify(signerCert.getPublicKey());
|
||||
signature.update(signedAttrsEncoded);
|
||||
byte[] rawSig = new byte[64];
|
||||
if (signatureValue.length >= 65 && signatureValue[0] == 0x30) {
|
||||
int offset = signatureValue[1] >= 0x81 ? (signatureValue[1] == 0x81 ? 3 : 2) : 2;
|
||||
if (signatureValue.length >= offset + 32 + 2) {
|
||||
System.arraycopy(signatureValue, offset + 1, rawSig, 0, 32);
|
||||
System.arraycopy(signatureValue, offset + 33, rawSig, 32, 32);
|
||||
valid = signature.verify(rawSig);
|
||||
System.out.println(" 原始格式验签结果: " + (valid ? "成功" : "失败"));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(" 原始格式验签失败: " + e.getMessage());
|
||||
if (authAttrsData instanceof ASN1TaggedObject) {
|
||||
System.out.println(" [GMT 0010-2012] 尝试使用两种方式验签:");
|
||||
|
||||
System.out.println("\n 方式1: 使用带标签的完整编码 (包含 [0] IMPLICIT 标签)");
|
||||
valid = verifySM2Signature(signerCert.getPublicKey(), signingData, signatureValue);
|
||||
|
||||
if (!valid) {
|
||||
System.out.println("\n 方式2: 使用标签内的原始数据 (不包含标签)");
|
||||
ASN1TaggedObject tagged = (ASN1TaggedObject) authAttrsData;
|
||||
ASN1Primitive inner = tagged.getObject();
|
||||
byte[] innerEncoded = inner.getEncoded(ASN1Encoding.DER);
|
||||
System.out.println(" 内部数据长度: " + innerEncoded.length + " bytes");
|
||||
System.out.println(" 内部数据 Hex: " + bytesToHex(innerEncoded));
|
||||
valid = verifySM2Signature(signerCert.getPublicKey(), innerEncoded, signatureValue);
|
||||
}
|
||||
} else {
|
||||
valid = verifySM2Signature(signerCert.getPublicKey(), signingData, signatureValue);
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
System.out.println("\n [调试] 尝试调整签名值格式...");
|
||||
valid = tryAlternativeFormats(signerCert.getPublicKey(), signingData, signatureValue);
|
||||
}
|
||||
|
||||
return new SignedAndEnvelopedVerifyResult(valid, messageDigest, signerCert,
|
||||
@ -693,6 +689,89 @@ public class CMSUtil {
|
||||
throw new Exception("未找到有效的签名信息");
|
||||
}
|
||||
|
||||
private static boolean verifySM2Signature(PublicKey publicKey, byte[] data, byte[] signature) {
|
||||
try {
|
||||
Signature sig = Signature.getInstance("SM3withSM2", "BC");
|
||||
sig.initVerify(publicKey);
|
||||
sig.update(data);
|
||||
boolean result = sig.verify(signature);
|
||||
System.out.println(" 验签结果: " + (result ? "成功" : "失败"));
|
||||
|
||||
if (!result && data.length > 0 && data[0] == 0x30) {
|
||||
System.out.println(" [GMT 0010-2012] 尝试将SEQUENCE转换为SET...");
|
||||
byte[] setData = convertSequenceToSet(data);
|
||||
if (setData != null) {
|
||||
sig = Signature.getInstance("SM3withSM2", "BC");
|
||||
sig.initVerify(publicKey);
|
||||
sig.update(setData);
|
||||
result = sig.verify(signature);
|
||||
System.out.println(" SET格式验签结果: " + (result ? "成功" : "失败"));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
System.out.println(" 验签失败: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] convertSequenceToSet(byte[] sequenceData) {
|
||||
try {
|
||||
if (sequenceData.length < 2 || sequenceData[0] != 0x30) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] setData = new byte[sequenceData.length];
|
||||
System.arraycopy(sequenceData, 0, setData, 0, sequenceData.length);
|
||||
setData[0] = 0x31;
|
||||
return setData;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean tryAlternativeFormats(PublicKey publicKey, byte[] data, byte[] signature) {
|
||||
try {
|
||||
if (signature.length >= 65 && signature[0] == 0x30) {
|
||||
System.out.println(" 尝试解析 ASN.1 编码的签名值...");
|
||||
int offset = 2;
|
||||
if (signature[1] >= 0x81) {
|
||||
offset = signature[1] == 0x81 ? 3 : 2 + (signature[1] & 0xFF);
|
||||
}
|
||||
|
||||
if (signature[offset] == 0x02) {
|
||||
int rLen = signature[offset + 1];
|
||||
byte[] r = new byte[rLen];
|
||||
System.arraycopy(signature, offset + 2, r, 0, rLen);
|
||||
offset += 2 + rLen;
|
||||
|
||||
if (signature[offset] == 0x02) {
|
||||
int sLen = signature[offset + 1];
|
||||
byte[] s = new byte[sLen];
|
||||
System.arraycopy(signature, offset + 2, s, 0, sLen);
|
||||
|
||||
byte[] rawSig = new byte[64];
|
||||
int rStart = r[0] == 0x00 ? 1 : 0;
|
||||
int sStart = s[0] == 0x00 ? 1 : 0;
|
||||
System.arraycopy(r, rStart, rawSig, 32 - r.length + rStart, r.length - rStart);
|
||||
System.arraycopy(s, sStart, rawSig, 64 - s.length + sStart, s.length - sStart);
|
||||
|
||||
Signature sig = Signature.getInstance("SM3withSM2", "BC");
|
||||
sig.initVerify(publicKey);
|
||||
sig.update(data);
|
||||
boolean result = sig.verify(rawSig);
|
||||
System.out.println(" 原始格式(R+S)验签结果: " + (result ? "成功" : "失败"));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(" 尝试其他格式失败: " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 1) {
|
||||
System.out.println("用法: java CMSUtil <base64_cms_data>");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user