Domanda

Dopo che un jar è stato firmato e è stata utilizzata l'opzione -tsa, come posso verificare che il timestamp sia stato incluso? Ho provato:

jarsigner -verify -verbose -certs myApp.jar

Ma l'output non specifica nulla sul timestamp. Lo sto chiedendo perché anche se ho un refuso nel percorso dell'URL -tsa, il jarsigner ha successo. Questo è l'URL TSA di GlobalSign: http://timestamp.globalsign.com/scripts/timstamp.dll e il server dietro di esso apparentemente accetta qualsiasi percorso (es. timestamp.globalsign.com/foobar), quindi alla fine non sono davvero sicuro che il mio vaso sia timestamp o meno.

È stato utile?

Soluzione

Ho appena trascorso le ultime 2 ore a cercare questo problema e alla fine ho trovato un modo per identificare se un file jar ha effettivamente informazioni sul timestamp nel file Blocco firme incluso. Ho potuto vedere il certificato GlobalSign nell'eseditor del file /META-INF/FOO.DSA, ma non ho trovato nessuno strumento che stampasse le informazioni di cui hai bisogno.

È possibile rinominare il file FOO.DSA in foo.p7b per aprirlo in Windows CertMgr, ma non mostra anche le informazioni di timestamp. Inoltre non sono riuscito a utilizzare OpenSSL per verificare il file DSA (è il formato di file PKCS # 7).

Quindi ho trovato il seguente codice che mostrerà il Time Stamp SignerInfo e la data in cui è stato creato il Timestamp. Spero sia un buon inizio per te. È necessario bcprov-jdk16-144.jar, bctsp-jdk16-144.jar e bcmail-jdk16-144.jar nel percorso di classe. Ricevili da 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;
        }
    }
}

Altri suggerimenti

Da https://blogs.oracle.com/mullan/entry/how_to_determine_if_a :

  

Puoi utilizzare l'utilità jarsigner per determinare se un JAR firmato è stato marcato come segue:

     

jarsigner -verify -verbose -certs signed.jar

     

dove signed.jar è il nome del JAR firmato. Se è timestamp, l'output includerà le righe seguenti che indicano l'ora in cui è stato firmato:

     

[la voce è stata firmata il 13/08/13 15:48]

     

Se il JAR non ha il timestamp, l'output non includerà quelle righe.

Java keytool può confermare se un JAR firmato è timestamp e può anche visualizzare il certificato TSA:

$ 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

...

mhaller fornisce un ottimo codice (printDSAInfos). Mi aiuta molto nel mio lavoro. Tuttavia sono necessarie alcune modifiche. La classe DEREncodable è ora cambiata in ASN1Encodable e il metodo getDERObject () è cambiato in ASN1Primitive. Quindi il codice è simile a questo

    ASN1Encodable dob = attribute.getAttrValues().getObjectAt(0);
    CMSSignedData signedData = new CMSSignedData(dob.toASN1Primitive().getEncoded());
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top