尝试验证 CBOR 消息上的签名时出错
Error trying to verify signature on CBOR message
我在使用 COSE-JAVA 解码欧盟数字证书(“Covid pass”)时遇到问题。 Public 密钥似乎加载正常,但当我尝试验证 CBOR 消息时,出现以下错误:
COSE.CoseException: Signature verification failure
at COSE.SignCommon.validateSignature(SignCommon.java:205)
at COSE.Signer.validate(Signer.java:212)
at COSE.Message.validate(Message.java:288)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at COSE.SignCommon.convertConcatToDer(SignCommon.java:212)
验证代码如下:
public static String DecodeMessage(byte[] data) throws CoseException, CborParseException {
Message m = Encrypt0Message.DecodeFromBytes(data);
PublicKey key = getPublicKey("here goes PEM of public key");
CborMap cborMap = CborMap.createFromCborByteArray(m.GetContent());
CounterSign signer = new CounterSign();
signer.setKey(new OneKey(key, null));
signer.addAttribute(HeaderKeys.Algorithm, AlgorithmID.ECDSA_256.AsCBOR(), Attribute.ProtectedAttributes);
// error happens here
m.validate(signer);
return cborMap.toJsonString();
}
这是从 PEM 生成 public 密钥的方式:
public static PublicKey getPublicKey(String keyData) {
try
{
Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider());
Reader rdr = new StringReader(
"-----BEGIN EC PUBLIC KEY-----\n" + keyData + "\n" + "-----END EC PUBLIC KEY-----\n"
);
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
byte[] content = spki.getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return KeyFactory.getInstance("EC", "BC").generatePublic(pubKeySpec);
}
catch (Exception ex)
{
return null;
}
Public 键定义为:
"publicKeyAlgorithm": {
"hash": {
"name": "SHA-256"
},
"name": "ECDSA",
"namedCurve": "P-256"
},
"publicKeyPem": "..."
Here is code 在 Python 中做同样的事情,可能会对某人有所帮助。代码必须在 Android 7.1 上运行(嵌入式设备,无法升级到更新的 Android)。
已解决...
public static boolean VerifySignature(byte[] data, String publicKey) {
boolean result = false;
try {
Message m = Encrypt0Message.DecodeFromBytes(data);
Sign1Message sm = (Sign1Message) m;
PublicKey key = getPublicKey(publicKey);
if (sm.validate(new OneKey(key, null))) {
result = true;
}
} catch (Exception ex) {
log.error("Error verifying signature", ex);
}
return result;
}
和
public static PublicKey getPublicKey(String keyData) {
try {
Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider());
Reader rdr = new StringReader(
"-----BEGIN EC PUBLIC KEY-----\n" + keyData + "\n" + "-----END EC PUBLIC KEY-----\n"
);
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
byte[] content = spki.getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return KeyFactory.getInstance("EC", "BC").generatePublic(pubKeySpec);
} catch (Exception ex) {
return null;
}
}
ODqaG8mnbro=": {
"serialNumber": "5dfefffd3a560d58",
"subject": "C=BE, O=eHealth - Belgium, CN=Belgium Covid19 DSC 01",
"issuer": "C=BE, O=eHealth - Belgium, CN=Belgium Covid19 Country Signing CA 01",
"notBefore": "2021-05-27T10:12:47.000Z",
"notAfter": "2023-05-27T10:12:47.000Z",
"signatureAlgorithm": "ECDSA",
"fingerprint": "2942d10907cf19f27aeb0dc391f35197c69dea87",
"publicKeyAlgorithm": {
"hash": {
"name": "SHA-256"
},
"name": "ECDSA",
"namedCurve": "P-256"
},
"publicKeyPem": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEU/f/KsmP3NasU/jZo7aulTrd9GHoznfnwWvX8xmHtK49EoobMAG7LhXnpLQ+aRwmmnSMcIWy8wPxM8QDMBUtyA=="
}
我在使用 COSE-JAVA 解码欧盟数字证书(“Covid pass”)时遇到问题。 Public 密钥似乎加载正常,但当我尝试验证 CBOR 消息时,出现以下错误:
COSE.CoseException: Signature verification failure
at COSE.SignCommon.validateSignature(SignCommon.java:205)
at COSE.Signer.validate(Signer.java:212)
at COSE.Message.validate(Message.java:288)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at COSE.SignCommon.convertConcatToDer(SignCommon.java:212)
验证代码如下:
public static String DecodeMessage(byte[] data) throws CoseException, CborParseException {
Message m = Encrypt0Message.DecodeFromBytes(data);
PublicKey key = getPublicKey("here goes PEM of public key");
CborMap cborMap = CborMap.createFromCborByteArray(m.GetContent());
CounterSign signer = new CounterSign();
signer.setKey(new OneKey(key, null));
signer.addAttribute(HeaderKeys.Algorithm, AlgorithmID.ECDSA_256.AsCBOR(), Attribute.ProtectedAttributes);
// error happens here
m.validate(signer);
return cborMap.toJsonString();
}
这是从 PEM 生成 public 密钥的方式:
public static PublicKey getPublicKey(String keyData) {
try
{
Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider());
Reader rdr = new StringReader(
"-----BEGIN EC PUBLIC KEY-----\n" + keyData + "\n" + "-----END EC PUBLIC KEY-----\n"
);
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
byte[] content = spki.getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return KeyFactory.getInstance("EC", "BC").generatePublic(pubKeySpec);
}
catch (Exception ex)
{
return null;
}
Public 键定义为:
"publicKeyAlgorithm": {
"hash": {
"name": "SHA-256"
},
"name": "ECDSA",
"namedCurve": "P-256"
},
"publicKeyPem": "..."
Here is code 在 Python 中做同样的事情,可能会对某人有所帮助。代码必须在 Android 7.1 上运行(嵌入式设备,无法升级到更新的 Android)。
已解决...
public static boolean VerifySignature(byte[] data, String publicKey) {
boolean result = false;
try {
Message m = Encrypt0Message.DecodeFromBytes(data);
Sign1Message sm = (Sign1Message) m;
PublicKey key = getPublicKey(publicKey);
if (sm.validate(new OneKey(key, null))) {
result = true;
}
} catch (Exception ex) {
log.error("Error verifying signature", ex);
}
return result;
}
和
public static PublicKey getPublicKey(String keyData) {
try {
Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider());
Reader rdr = new StringReader(
"-----BEGIN EC PUBLIC KEY-----\n" + keyData + "\n" + "-----END EC PUBLIC KEY-----\n"
);
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
byte[] content = spki.getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return KeyFactory.getInstance("EC", "BC").generatePublic(pubKeySpec);
} catch (Exception ex) {
return null;
}
}
ODqaG8mnbro=": {
"serialNumber": "5dfefffd3a560d58",
"subject": "C=BE, O=eHealth - Belgium, CN=Belgium Covid19 DSC 01",
"issuer": "C=BE, O=eHealth - Belgium, CN=Belgium Covid19 Country Signing CA 01",
"notBefore": "2021-05-27T10:12:47.000Z",
"notAfter": "2023-05-27T10:12:47.000Z",
"signatureAlgorithm": "ECDSA",
"fingerprint": "2942d10907cf19f27aeb0dc391f35197c69dea87",
"publicKeyAlgorithm": {
"hash": {
"name": "SHA-256"
},
"name": "ECDSA",
"namedCurve": "P-256"
},
"publicKeyPem": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEU/f/KsmP3NasU/jZo7aulTrd9GHoznfnwWvX8xmHtK49EoobMAG7LhXnpLQ+aRwmmnSMcIWy8wPxM8QDMBUtyA=="
}