2009-10-30 12 views
18

Bir kavanoz imzalandıktan ve -tsa seçeneği kullanıldıktan sonra, zaman damgasının dahil edildiğini nasıl doğrulayabilirim? Denedim: çıktı, zaman damgasıyla ilgili herhangi bir şey belirtmiyor. Ben soruyorum çünkü -tsa URL yolunda bir yazım hatası olsa bile, jarsigner başarılı olur. Bu, GlobalSign TSA URL'sidir: http://timestamp.globalsign.com/scripts/timstamp.dll ve arkasındaki sunucu görünüşe göre herhangi bir yolu kabul eder (yani. Timestamp.globalsign.com/foobar), bu yüzden de sonunda kavanozumun zaman damgalı olduğundan emin değilim.İmzalı bir kavanozda zaman damgası varsa nasıl onaylanır?

cevap

9

Bu sorunu arayan son 2 saati harcadım ve nihayet bir jar dosyasının gerçekten de Signature Block dosyasında yer alan zaman damgası bilgisine sahip olup olmadığını belirleme yolu bulduk. /META-INF/FOO.DSA dosyasının hexeditor'unda GlobalSign sertifikasını görebiliyordum, ancak ihtiyacınız olan bilgileri basacak herhangi bir araç bulamadım.

Windows CertMgr'de açmak için FOO.DSA dosyasını foo.p7b'ye yeniden adlandırabilirsiniz, ancak herhangi bir zaman damgası bilgisini de göstermez. Ayrıca DSA dosyasını doğrulamak için OpenSSL'yi kullanmadım (Bu PKCS # 7 dosya formatı).

Zaman Damgası SignerInfo'yu ve Zaman Damgasının oluşturulduğu tarihi gösteren aşağıdaki kodla geldim. Umarım bu sizin için iyi bir başlangıçtır. Sınıf yolunda bcprov-jdk16-144.jar, bctsp-jdk16-144.jar ve bcmail-jdk16-144.jar gerekir. https://blogs.oracle.com/mullan/entry/how_to_determine_if_a itibaren Bouncycastle

package de.mhaller.bouncycastle; 

import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.security.Security; 
import java.util.Collection; 
import java.util.jar.JarEntry; 
import java.util.jar.JarInputStream; 

import org.bouncycastle.asn1.DEREncodable; 
import org.bouncycastle.asn1.cms.Attribute; 
import org.bouncycastle.asn1.cms.AttributeTable; 
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 
import org.bouncycastle.cms.CMSException; 
import org.bouncycastle.cms.CMSSignedData; 
import org.bouncycastle.cms.SignerId; 
import org.bouncycastle.cms.SignerInformation; 
import org.bouncycastle.cms.SignerInformationStore; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.tsp.TSPException; 
import org.bouncycastle.tsp.TimeStampToken; 
import org.bouncycastle.tsp.TimeStampTokenInfo; 

public class VerifyTimestampSignature { 

    private static boolean found; 

    public static void main(String[] args) throws Exception { 
     if (args == null || args.length != 1) { 
      System.out.println("usage: java " + VerifyTimestampSignature.class.getName() 
        + " [jar-file|dsa-file]"); 
      return; 
     } 

     BouncyCastleProvider provider = new BouncyCastleProvider(); 
     Security.addProvider(provider); 

     String filename = args[0]; 

     if (filename.toLowerCase().endsWith(".dsa")) { 
      InputStream dsa = new FileInputStream(filename); 
      printDSAInfos(filename, dsa); 
      return; 
     } 

     if (filename.toLowerCase().endsWith(".jar")) { 
      InputStream jar = new FileInputStream(filename); 
      JarInputStream jarInputStream = new JarInputStream(jar); 
      JarEntry nextJarEntry; 
      do { 
       nextJarEntry = jarInputStream.getNextJarEntry(); 
       if (nextJarEntry == null) { 
        break; 
       } 
       if (nextJarEntry.getName().toLowerCase().endsWith(".dsa")) { 
        printDSAInfos(nextJarEntry.getName(), jarInputStream); 
       } 
      } while (nextJarEntry != null); 
     } 

     if (!found) { 
      System.out.println("No certificate with time stamp information found in " + filename); 
     } else { 
      System.out.println("Found at least one time stamp info"); 
      System.out.println("Note: But it was NOT verified for validity!"); 
     } 
    } 

    private static void printDSAInfos(String file, InputStream dsa) throws CMSException, 
      IOException, TSPException { 
     System.out.println("Retrieving time stamp token from: " + file); 
     CMSSignedData signature = new CMSSignedData(dsa); 
     SignerInformationStore store = signature.getSignerInfos(); 
     Collection<?> signers = store.getSigners(); 
     for (Object object : signers) { 
      SignerInformation signerInform = (SignerInformation) object; 
      AttributeTable attrs = signerInform.getUnsignedAttributes(); 
      if (attrs == null) { 
       System.err 
         .println("Signer Information does not contain any unsigned attributes. A signed jar file with Timestamp information should contain unsigned attributes."); 
       continue; 
      } 
      Attribute attribute = attrs.get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); 
      DEREncodable dob = attribute.getAttrValues().getObjectAt(0); 
      CMSSignedData signedData = new CMSSignedData(dob.getDERObject().getEncoded()); 
      TimeStampToken tst = new TimeStampToken(signedData); 

      SignerId signerId = tst.getSID(); 
      System.out.println("Signer: " + signerId.toString()); 

      TimeStampTokenInfo tstInfo = tst.getTimeStampInfo(); 
      System.out.println("Timestamp generated: " + tstInfo.getGenTime()); 
      found = true; 
     } 
    } 
} 
+0

gibi görünüyor. Ayrıca CMS şeyler için bcmail-jdk16-144.jar gerekiyor – user199092

+0

Çaba ve zaman için çok teşekkür ederim. – Edenshaw

+1

Ben de işe aldım, ancak bunun yerine rsa'yı kontrol etmek için 'endsWith (".dsa")' yı değiştirmek zorundaydım. – JimN

15

onları alın:

jarsigner -verify -verbose -certs signed.jar

signed.jar olduğu: imzalı JAR timestamped edilmişse şöyle

belirlemek için jarsigner yardımcı programını kullanabilirsiniz imzalı JAR'ın adı. o timestamped ise, çıkış imzalandıktan zamanı gösteren aşağıdakilerden hatları içerecektir: JAR timestamped değildir

[entry was signed on 8/2/13 3:48 PM]

, çıktı bu satırları içermez.

+1

Bu aslında en iyi cevap! – thokuest

+0

Bu parti için biraz geç, ancak sindirim algıları önemli ise önemli olabilir. Zaman damgasını nasıl gördüğünü görmeniz gerekiyorsa, jdk8u111 veya daha yeni bir jarsigner'a ihtiyacınız olacak.Daha sonra, -Verify -verbose -certs ile, sonunda size gösterecektir: "Zaman damgası sindirim algoritması: SHA-1, Zaman damgası imza algoritması: SHA1withRSA, 2048 bit anahtar". Eğer SHA-256 ve SHA256 karması sorun yaratacağı karışık java7 kurulumlarını desteklemeniz gerekiyorsa o zaman önemlidir. –

5

Java en keytool imzalı JAR timestamped olup olmadığını teyit edebilir ve ayrıca TSA sertifikasını görüntüleyebilir:

$ keytool -printcert -jarfile myApp.jar 

... 

Timestamp: 

Owner: CN=GeoTrust Timestamping Signer 1, O=GeoTrust Inc, C=US 
Issuer: CN=Thawte Timestamping CA, OU=Thawte Certification, O=Thawte, L=Durbanville, ST=Western Cape, C=ZA 
Serial number: 5e8d2daca44665546bb587978191a8bf 
Valid from: Wed Oct 31 00:00:00 GMT 2007 until: Mon Oct 30 23:59:59 GMT 2017 
Certificate fingerprints: 
    MD5: E5:30:07:8E:91:8D:A0:6C:18:6D:91:2A:B6:D2:3A:56 
    SHA1: 22:3C:DA:27:07:96:73:81:6B:60:8A:1B:8C:B0:AB:02:30:10:7F:CC 
    SHA256: D7:B8:44:BD:39:5A:17:36:02:39:51:C6:4D:6C:81:65:45:93:AD:29:1D:DC:E4:6C:8D:79:B6:65:DF:31:0C:F6 
    Signature algorithm name: SHA1withRSA 
    Version: 3 

... 
1

mhaller harika kodu (printDSAInfos) sağlar. İşimde bana çok yardımcı oluyor. Ancak birkaç değişiklik gerekli. DEREncodable sınıfı artık ASN1Encodable olarak değiştirildi ve getDERObject() yöntemi toASN1Primitive olarak değiştirildi. Bu nedenle kod, bu