2011-04-07 29 views
6

Bir jar dosyasının açık bir şekilde kurcalanmadığını program aracılığıyla doğrulamaya çalışıyorum. Önlemek istediğim 2 kullanım vakam var. kavanozKavanoz İmzasının Doğrulanması

varolan sınıfları 2) yeni sınıflarının eklemeler 1) değişiklikler I jarsigner kullanılarak kavanoz imza. Yukarıdaki durumlardan birini jarsigner ile doğruladığımda beklediğim gibi çalışır.

Ben ancak How to verify a jar signed with jarsigner programmatically veya How to verify signature on self signed jar? yılında programlı örneklerini kullanarak bunu deneyin

, ben bu konuda hiç bir SecurityExceptions ... veya herhangi bir istisna alamadım.

Bu parçacıkların diğer insanlar için çalıştığı göründüğü için yanlış yaptığımdan emin değilim. Herhangi bir fikir? Bu JDK 1.6 BTW.

Düzenleme: , aşağıdaki kod örneği istediği gibi ... Aşağıdaki örneği kullanarak kendi modifiye kavanoz :)

JarFile myJar; 

    try 
    { 
     //Insert the full path to the jar here  
     String libPath = "" 
     stature = new JarFile(libPath,true); 

     //Don't really need this right now but was using it to inspect the SHA1 hashes 

     InputStream is = myJar.getInputStream(myJar.getEntry("META-INF/MANIFEST.MF")); 
     Manifest man = myJar.getManifest();    
     is.close(); 

     verifyJar(myJar); 

    } 
    catch (IOException ioe) 
    { 
     throw new Exception("Cannot load jar file", ioe); 
    } 


private void verifyJar(JarFile jar) throws Exception 
{ 
    Enumeration<java.util.jar.JarEntry> entries = jar.entries(); 
    while (entries.hasMoreElements()) 
    { 
     java.util.jar.JarEntry entry = entries.nextElement(); 

     try 
     { 
      jar.getInputStream(entry); 

      //Also tried actually creating a variable from the stream in case it was discarding it before verification 
      //InputStream is = jar.getInputStream(entry); 
      //is.close(); 
     } 
      catch (SecurityException se) 
      { 
       /* Incorrect signature */      
       throw new Exception("Signature verification failed", se); 
      } 
      catch (IOException ioe) 
      { 
       throw new Exception("Cannot load jar file entry", ioe); 
      } 
    } 
} 

+0

JAR testi altında nasıl müdahale ettiniz? – trashgod

+0

7zip'te açtım. Bazı sınıf dosyaları ile yeni bir paket dizini ekledim ve mevcut sınıf dosyalarının bir kısmını yeniden derlenmiş sürümlerle değiştirdim. – Amasuriel

+0

Eğer jarsigner değiştirilmiş JAR'ı reddederse, ancak kodunuz bunu kabul ederse, bir [sscce] (http://sscce.org/) problemi tespit edebilir. – trashgod

cevap

1

Bunun neden böyle olduğunu anladım ... bu aptalca bir hataydı.

Kurcalanmış imzalı kavanozumu yaptım, ama aynı zamanda benim de env'im olduğu için derlenen bütün sınıflar da vardı. Böylece sınıf yükleyici, derlenmiş sınıfları kavanoz sınıfları üzerinde topladı. Derlenmiş sınıflar için bir bildirim yoktur, dolayısıyla hiçbir güvenlik hatası oluşturulmamıştır.

Derlenmiş sınıflarımı sildikten sonra beklenen güvenlik özel durumlarını aldım.

7

kaynağı, bir doğru imzalı JAR için (true) beklenen sonucu elde ve değiştirilmiş bir JAR (false). Testin etkisini tetiklemenin basit bir yolu, META-INF/MANIFEST.MF'da listelenen özetlerden birini değiştirmektir.

Bu yaklaşımın, bildiride listelenen numaralı numaralı girdileri yok saydığını unutmayın. jarsigner -verify raporlarını kullanarak, "Bu jar, bütünlük denetimi yapılmayan işaretsiz girişleri içerir." Akışı tamamen okuduktan sonra, bir girişin herhangi bir işareti olup olmadığını belirlemek için entry.getCodeSigners() kullanılabilir.

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Enumeration; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 

/** @see http://stackoverflow.com/questions/5587656 */ 
public class Verify { 

    public static void main(String[] args) throws IOException { 
     System.out.println(verify(new JarFile(args[0]))); 
    } 

    private static boolean verify(JarFile jar) throws IOException { 
     Enumeration<JarEntry> entries = jar.entries(); 
     while (entries.hasMoreElements()) { 
      JarEntry entry = entries.nextElement(); 
      try { 
       byte[] buffer = new byte[8192]; 
       InputStream is = jar.getInputStream(entry); 
       while ((is.read(buffer, 0, buffer.length)) != -1) { 
        // We just read. This will throw a SecurityException 
        // if a signature/digest check fails. 
       } 
      } catch (SecurityException se) { 
       return false; 
      } 
     } 
     return true; 
    } 
} 

Not: JDK 8 için, sadece giriş akışı almak için onun yeterli değildir. jarsigner'da olduğu gibi akış da okunmalıdır. Yukarıdaki kodda, girdi akışını aldıktan sonra jar signersource'dan uyarlanan bir döngü eklenmiştir.

+0

Hmm. Numuneniz benimkiyle neredeyse aynı, ancak güvenlik istisnaları alıyorsunuz ve ben yok. Tam olarak hangi JDK kullanıyorsunuz? – Amasuriel

+0

Sürümünün önemi yok. 'SecurityException' yalnızca bir giriş yanlış bir şekilde imzalanmışsa atılır. Ayrıca, 'META-INF/ .SF' ile kurcalayarak da tetikleyebilirsiniz. – trashgod

+0

Ben bunu çoğu kişi için işe yaradığı için bu cevabı işaret olarak işaretleyeceğim. Bir şans elde ettiğimde daha basit bir örnekle deneyeceğim ... Eğer bunun benim için neden işe yaramadığını anlamaya çalışırsam nasıl düzelteceğimi tahmin edersem sanırım yeni bir soru açacağım. – Amasuriel