Pregunta

Estoy queriendo firmar un frasco usando jarsigner, a continuación, compruebe que el uso de una aplicación Java que no tiene el frasco firmado como parte de su ruta de clase (es decir, simplemente utilizando una ubicación de sistema de archivos de la jarra)

Ahora mi problema es conseguir el archivo de firma de la jarra, hay una manera simple de hacer esto?

He tenido un juego con los InputStreams Inflater y frasco con ninguna suerte.

O es algo que se puede lograr de una manera mejor?

Gracias

¿Fue útil?

Solución

La proveedor de seguridad guía de implementación describe el proceso de verificación de los frascos. A pesar de que estas instrucciones son para un proveedor de servicios de cifrado JCA para verificar sí, deben ser aplicables a su problema.

Específicamente, revisar el método verify(X509Certificate targetCert) en el código de ejemplo, "MyJCE.java" .

Otros consejos

Usted puede simplemente abrir el frasco con java.util.jar.JarFile y decirle que para verificar el archivo JAR. Si se firma el JAR, entonces JarFile tiene la opción de verificar que (que está activado por defecto). Sin embargo, también abrirá JarFile no firmados felizmente, por lo tanto, también debe comprobar, si el archivo está firmado. Puede hacerlo mediante la comprobación del manifiesto del JAR para * -Digest atributos:. Se firman elementos con un atributo como atributo

Ejemplo:

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);

Puede utilizar entry.getCodeSigners () para obtener los firmantes de una entrada en particular en el frasco.

Asegúrese de abrir la JarFile con verificación = true y leer completamente la entrada JAR antes de llamar entry.getCodeSigners ().

Algo como esto podría ser utilizado para verificar cada entrada que no es un archivo de 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();
    }
 }

Puede utilizar la aplicación jarsigner para hacer esto. En ProcessBuilder (o Runtime.exec) puede ejecutar el comando con estos argumentos

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

y si los contians salida verifican entonces se firma el frasco

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");
...

Hay cosas más complicadas que puede hacer cuando se tiene la salida del código jarsigner.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top