Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将修改后的清单文件转换回JarEntry_Java_Maven_Jar_Manifest.mf - Fatal编程技术网

Java 将修改后的清单文件转换回JarEntry

Java 将修改后的清单文件转换回JarEntry,java,maven,jar,manifest.mf,Java,Maven,Jar,Manifest.mf,在工作中,我们使用了很多已经签名的第三方库。其中一些已不再维护,但我们仍需要使用它们。由于最近的Java安全更新,这些JAR中的清单文件需要更新以包含额外的安全属性。考虑到jar文件的工作方式,我需要对每个jar执行解包编辑重新打包过程 这涉及到解包jar,向清单中添加额外属性,同时删除已经存在的SHA1签名字符串,使用我们自己的签名重新打包和调整jar。以下是我到目前为止用来解包jar的代码: public static void unpackJarFile(File srcJarFile)

在工作中,我们使用了很多已经签名的第三方库。其中一些已不再维护,但我们仍需要使用它们。由于最近的Java安全更新,这些JAR中的清单文件需要更新以包含额外的安全属性。考虑到jar文件的工作方式,我需要对每个jar执行解包编辑重新打包过程

这涉及到解包jar,向清单中添加额外属性,同时删除已经存在的SHA1签名字符串,使用我们自己的签名重新打包和调整jar。以下是我到目前为止用来解包jar的代码:

public static void unpackJarFile(File srcJarFile) throws IOException{
    File tmpJarFile = File.createTempFile("tempJar", ".tmp");
    JarFile jarFile = new JarFile(srcJarFile);
    JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(tmpJarFile));

    //Copy original jar file to the temporary one.
    Enumeration<JarEntry> jarEntries = jarFile.entries();
    while(jarEntries.hasMoreElements()) {
        JarEntry temp = jarEntries.nextElement();

        //if file is manifest then unsign else carry on
        JarEntry entry = isManifestFile(temp) ? unsignManifest(temp, jarFile) : temp;
        // ingore files ending in .SF and .RSA
        if (fileIsNotSignature(entry)){
            InputStream entryInputStream = jarFile.getInputStream(entry);
            tempJarOutputStream.putNextEntry(entry);
            byte[] buffer = new byte[1024];
            int bytesRead = 0;
            while ((bytesRead = entryInputStream.read(buffer)) != -1) {
                tempJarOutputStream.write(buffer, 0, bytesRead);
            }
        }
    }
    tempJarOutputStream.close();
    jarFile.close();
    srcJarFile.delete();
    tmpJarFile.renameTo(srcJarFile);
}

  private static JarEntry unsignManifest(JarEntry signed, JarFile jarFile) throws IOException {

    //extract signed manifest contents into a temp text file
    File tmpManifestFile = File.createTempFile("tempManifest", ".tmp");
    tmpManifestFile.deleteOnExit();
    Manifest manifest = jarFile.getManifest();
    OutputStream fos = new FileOutputStream(tmpManifestFile);

    //write out manifest contents to an actual file on disk for later editing
    manifest.write(fos);
    fos.close();

    //read the physical file back in line by line so that SHA1 strings 
    //can be ignored when creating a new manifest file.
    Path path = Paths.get(tmpManifestFile.getPath());
    List<String> lines = Files.readAllLines(path, Charset.defaultCharset());

    // some logic here. Something like
    // for each line : lines
    // if !line.contains("SHA1-Digest: SWDa1ic/T+le1N+UvrAYf89lY4E=")
    // write it out to the new manifest file
    // append extra security attributes
    //convert new manifest file to new JarEntry unsigned
    // return JarEntry

    return unsigned;

}
publicstaticvoidunpackjarfile(文件srcJarFile)引发IOException{
File tmpJarFile=File.createTempFile(“tempJar”,“.tmp”);
JarFile JarFile=新的JarFile(srcJarFile);
JarOutputStream tempJarOutputStream=newjaroutputstream(newfileoutputstream(tmpJarFile));
//将原始jar文件复制到临时jar文件。
枚举jarEntries=jarFile.entries();
while(jarEntries.hasMoreElements()){
JarEntry temp=jarEntries.nextElement();
//如果文件是清单,则不签名,否则继续
JarEntry entry=isManifestFile(temp)?unsignManifest(temp,jarFile):temp;
//以.SF和.RSA结尾的ingore文件
如果(文件不是签名(条目)){
InputStream entryInputStream=jarFile.getInputStream(条目);
tempJarOutputStream.putNextEntry(条目);
字节[]缓冲区=新字节[1024];
int字节读取=0;
而((bytesRead=entryInputStream.read(缓冲区))!=-1){
写入(缓冲区,0,字节读取);
}
}
}
tempJarOutputStream.close();
jarFile.close();
srcJarFile.delete();
tmpJarFile.renameTo(srcJarFile);
}
私有静态JarEntry unsignManifest(JarEntry已签名,JarFile JarFile)引发IOException{
//将签名清单内容提取到临时文本文件中
File tmpManifestFile=File.createTempFile(“tempManifest”、“.tmp”);
tmpManifestFile.deleteOnExit();
Manifest Manifest=jarFile.getManifest();
OutputStream fos=新文件OutputStream(tmpManifestFile);
//将清单内容写入磁盘上的实际文件,以便以后编辑
舱单写入(fos);
fos.close();
//逐行读取物理文件,使SHA1字符串
//创建新清单文件时可以忽略。
Path Path=Path.get(tmpManifestFile.getPath());
列表行=Files.readAllLines(路径,Charset.defaultCharset());
//这里有些逻辑,比如
//每行:行
//if!line.contains(“SHA1摘要:SWDa1ic/T+le1N+UvrAYf89lY4E=”)
//将其写入新的清单文件
//附加额外的安全属性
//将新清单文件转换为未签名的新条目
//返回项
未签名返回;
}
考虑到Java的JarEntry和Manifest类的单向性,看起来我必须完成所有繁重的工作。我可以把这些值拿出来,但在我看来,选择性地把它们放进去是痛苦的。到目前为止,我可以打开包装并重新包装罐子。正如您在代码末尾所看到的,我只是不知道如何有选择地将内容放回清单文件并将其转换为JarEntry,以便unpackJarFile()方法认为新创建的清单文件来自原始jar

提前谢谢