Domanda

Sono voler firmare un barattolo con jarsigner, quindi verificare utilizzando un'applicazione Java che non ha firmato il vaso, come parte del suo percorso di classe (vale a dire usando solo una posizione del file system del vaso)

Ora il mio problema è ottenere il file delle firme fuori dal vaso, c'è un modo semplice per fare questo?

Ho avuto un gioco con le InputStreams gonfiatore e vaso senza fortuna.

O è qualcosa che può essere realizzato in un modo migliore?

Grazie

È stato utile?

Soluzione

Il fornitore di sicurezza di guida all'implementazione delinea il processo di verifica JAR. Anche se queste istruzioni sono per un JCA Cryptographic Service Provider per verificare se stessa, dovrebbero essere applicabili al vostro problema.

In particolare, controlla il metodo verify(X509Certificate targetCert) nel codice di esempio, "MyJCE.java" .

Altri suggerimenti

Si può semplicemente aprire il vaso con java.util.jar.JarFile e dire che per verificare il file JAR. Se il vaso è firmato, quindi JarFile ha la possibilità di verificarlo (che è attiva per impostazione predefinita). Tuttavia, JarFile aprirà anche JAR firmati felicemente, quindi, è necessario anche verificare, se il file è firmato. È possibile farlo controllando manifesta del JAR per * -Digest attributi:. Elementi con tale attributo attributi sono firmati

Esempio:

JarFile jar = new JarFile(new File("path/to/your/jar-file"));

// This call will throw a java.lang.SecurityException if someone has tampered
// with the signature of _any_ element of the JAR file.
// Alas, it will proceed without a problem if the JAR file is not signed at all
InputStream is = jar.getInputStream(jar.getEntry("META-INF/MANIFEST.MF"));
Manifest man = new Manifest(is);
is.close();

Set<String> signed = new HashSet();
for(Map.Entry<String, Attributes> entry: man.getEntries().entrySet()) {
    for(Object attrkey: entry.getValue().keySet()) {
        if (attrkey instanceof Attributes.Name && 
           ((Attributes.Name)attrkey).toString().indexOf("-Digest") != -1)
            signed.add(entry.getKey());
    }
}

Set<String> entries = new HashSet<String>();
for(Enumeration<JarEntry> entry = jar.entries(); entry.hasMoreElements(); ) {
    JarEntry je = entry.nextElement();
    if (!je.isDirectory())
        entries.add(je.getName());
}

// contains all entries in the Manifest that are not signed.
// Ususally, this contains:
//  * MANIFEST.MF itself
//  * *.SF files containing the signature of MANIFEST.MF
//  * *.DSA files containing public keys of the signer

Set<String> unsigned = new HashSet<String>(entries);
unsigned.removeAll(signed);

// contains all the entries with a signature that are not present in the JAR
Set<String> missing = new HashSet<String>(signed);
missing.removeAll(entries);

È possibile utilizzare entry.getCodeSigners () per ottenere i firmatari per una particolare voce nel JAR.

Assicurati di aprire il JarFile con verifica = true e di leggere completamente la voce prima di chiamare JAR entry.getCodeSigners ().

Qualcosa di simile potrebbe essere utilizzato per verificare ogni voce che non è un file di firma:

boolean verify = true;
JarFile jar = new JarFile(signedFile, verify);

// Need each entry so that future calls to entry.getCodeSigners will return anything
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
   JarEntry entry = entries.nextElement();
   IOUtils.copy(jar.getInputStream(entry), new NullOutputStream());
}

// Now check each entry that is not a signature file
entries = jar.entries();
while (entries.hasMoreElements()) {
    JarEntry entry = entries.nextElement();
    String fileName = entry.getName().toUpperCase(Locale.ENGLISH);
    if (!fileName.endsWith(".SF")
       && !fileName.endsWith(".DSA")
       && !fileName.endsWith(".EC")
       && !fileName.endsWith(".RSA")) {

       // Now get code signers, inspect certificates etc here...
       // entry.getCodeSigners();
    }
 }

È possibile utilizzare l'applicazione jarsigner per fare questo. In ProcessBuilder (o Runtime.exec) è possibile eseguire il comando con questi argomenti

 ProcessBulider pb = new ProcessBuilder("/usr/bin/jarsigner", "-verify", "-certs", f.getAbsolutePath());

e se i contians uscita verificati allora è firmato il vaso

Process p = pb.start();
p.waitFor();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
if(line.contains("verified");
...

Ci sono cose più complicate si possono fare quando si ha l'uscita del codice jarsigner.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top