我有以下代码:
public class Properties {
public static void main(String[] args) throws Exception {
Files.writeString(Path.of("anything"), "anything");
JarUtils.createJarFile(Path.of("src.jar"), Path.of("."),
Files.write(Path.of("anything"), new byte[100]));
var cakg = new CertAndKeyGen("EC", "SHA1withECDSA");
cakg.generate("secp256r1");
JarSigner.Builder jsb = new JarSigner.Builder(
cakg.getPrivateKey(),
CertificateFactory.getInstance("X.509").generateCertPath(List.of(
cakg.getSelfCertificate(new X500Name("CN=Me"), 100))));
jsb.signerName("E");
String sf;
byte[] i0 = sign(jsb.setProperty("internalsf", "false"));
// EncapsulatedContentInfo no content
DerUtils.shouldNotExist(i0, "1021");
byte[] i1 = sign(jsb.setProperty("internalsf", "true"));
// EncapsulatedContentInfo has content being the SF
sf = new String(DerUtils.innerDerValue(i1, "10210").getOctetString());
Asserts.assertTrue(sf.startsWith("Signature-Version"));
// There is a SignedAttributes
byte[] d0 = sign(jsb);
Asserts.assertTrue(DerUtils.innerDerValue(d0, "10403")
.isContextSpecific((byte)0));
// Has a hash for the whole manifest
byte[] s0 = sign(jsb.setProperty("sectionsonly", "false"));
sf = new String(DerUtils.innerDerValue(s0, "10210").getOctetString());
Asserts.assertTrue(sf.contains("SHA-256-Digest-Manifest:"));
// Has no hash for the whole manifest
byte[] s1 = sign(jsb.setProperty("sectionsonly", "true"));
sf = new String(DerUtils.innerDerValue(s1, "10210").getOctetString());
Asserts.assertFalse(sf.contains("SHA-256-Digest-Manifest:"));
}
// Sign and returns the content of the PKCS7 signature block inside
static byte[] sign(JarSigner.Builder b) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try (ZipFile zf = new ZipFile("src.jar")) {
b.build().sign(zf, bout);
}
var jf = new JarInputStream(
new ByteArrayInputStream(bout.toByteArray()));
while (true) {
JarEntry je = jf.getNextJarEntry();
if (je == null) {
throw new RuntimeException("Cannot find signature");
}
if (je.getName().equals("META-INF/E.EC")) {
return jf.readAllBytes();
}
}
}
}
具体来说,断言
Asserts.assertTrue(sf.contains("SHA-256-Digest-Manifest:"))
失败了。此断言检查当 sign()
属性设置为 false 时 sectionsonly
方法的输出是否包含整个清单的散列。哈希应该包含在签名 JAR 文件的 SF 文件中,测试从 sign()
方法返回的字节数组中读取它。
断言失败表明SF文件不包含预期的散列。我尝试打印出
sf
的 sf = new String(DerUtils.innerDerValue(i1, "10210").getOctetString());
值,但输出没有显示在我的堆栈跟踪中。另外,我尝试添加sf = new String(DerUtils.innerDerValue(i1, "10210").getOctetString(StandardCharsets.UTF_8));
以查看是否存在编码问题,但语法似乎有误。任何见解都会有所帮助。