简体   繁体   English

如何从签名的 jar 文件中创建或提取证书

[英]How do I create or extract the certificate from a signed jar file

I am working on extracting the metadata from jar file.我正在从 jar 文件中提取元数据。 One of the metadata component is the certificate.元数据组件之一是证书。 I have a signed jar file that has *.DSA and *.SC files generated.我有一个签名的 jar 文件,其中生成了 *.DSA 和 *.SC 文件。 Is there a way to programmatically create a certificate file from these files in java?有没有办法以编程方式从 Java 中的这些文件创建证书文件?

A signed jar should have (for each signature, if more than one)一个签名的罐子应该有(对于每个签名,如果不止一个)

  • a signer.SF (not .SC ) entry which, like the manifest, has some global attributes plus a digest of each jar entry (class, resource, etc) covered by the signature and一个signer.SF (不是.SC )条目,与清单一样,它具有一些全局属性以及签名所涵盖的每个 jar 条目(类、资源等)的摘要和

  • a signer.{RSA,DSA,EC} entry which is a PKCS7 (aka CMS) 'detached' signature.一个signer.{RSA,DSA,EC}条目,它是一个 PKCS7(又名 CMS)“分离”签名。 Such a PKCS7/CMS signature can and usually (at least from jarsigner ) does contain the signer's cert chain -- or more exactly the certs making up that chain, since cert chains are normally ordered (certainly they are in a Java keystore) but the certs in a PKCS7/CMS SignedData are defined in ASN.1 as a SET which doesn't preserve order.这样的 PKCS7/CMS 签名可以而且通常(至少来自jarsigner )确实包含签名者的证书——或者更确切地说是构成该链的证书,因为证书链通常是有序的(当然它们在 Java 密钥库中),但是PKCS7/CMS SignedData 中的证书在 ASN.1 中定义为不保留顺序的 SET。

'Plain' Java does not expose classes for dealing with PKCS7 (although they exist internally), but if you can use (add) bcprov from https://www.bouncycastle.org it does and you can use code like this to write the certs as DER or PEM files: 'Plain' Java 不公开用于处理 PKCS7 的类(尽管它们存在于内部),但如果您可以使用(添加)来自https://www.bouncycastle.org的 bcprov,则可以使用这样的代码来编写证书作为 DER 或 PEM 文件:

import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
...
    byte[] sig = // contents of the signer.RSA/DSA/EC entry e.g. using ZipFile
    int n = 0; boolean DER = // true or false as desired
    for( X509CertificateHolder cert : new CMSSignedData(sig).getCertificates().getMatches(null) ){
        byte[] der = cert.getEncoded(); String filename = "cert"+(++n);
        if( DER ) Files.write(Paths.get(filename), der);
        else try( PemWriter w = new PemWriter(new FileWriter(filename)) ){
            w.writeObject( new PemObject("CERTIFICATE",der) );
        }
    }

Of course instead of writing files, you can do other storage or processing in the loop.当然,您可以在循环中进行其他存储或处理,而不是写入文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM