I'm writing a Java Class which extends Ant Zip Task to do a particular job for me. I want to create a zip file and once that file is created, I want to suppress the access time in the inode so I can't be modified or find a way to not let it change, even if the file is modified. The reason for that is I made a md5 hash which depends on the access time. Thus that's giving me a lot of trouble, and making the access time constant will solve my problem.
Does someone now how would I accomplish that?
Thanks!
I've had to solve a similar problem previously - perhaps this is an option for you. In my case, the problem was:
We made a jar file and then ran an secure hash algorithm on the jar file. Because the jar file is really a zip file, and a zip file internally contains file metadata information including last access time, if we create a new jar file from the exact same source material, then the hash on the new jar file doesn't match the original hash (because while the zip contents are the same, the metadata stored in the zip file has different file creation / access times).
Basically, we needed to be able to compute a secure hash for compliance purposes to be able to easily show that the contents of a jar was unchanged. Recompiling an equivalent jar was ok - it's just that the contents had to be identical.
We wrote a simple set of tools that performed secure hashes (and verifications) specifically for zip/jar files. It computed two hashes:
a regular secure hash of the file (which would identify the exact same jar - this would be the same as the output of your standard md5sum)
a "content only" hash which was computed by iterating over the bytes of the unpacked contents of the zip/jar (and thus could be used to identify that a recompiled jar matched the original jar)
To implement the content only hash, we used a ZipInputStream to iterate over the zip entries.
MessageDigest sha1;
byte[] digest;
for (each zip file entry)
{
if (entry represents a directory)
{
sha1.update( directory name bytes as UTF-8 );
}
else
{
read the entry bytes using ZipInputStream.read()
sha1.update( bytes );
}
}
digest = sha1.digest();
See also: ZipInputStream.read()
Note, however, that some files such as the manifest can contain information such as the version of ant used to create the jar, and the version of the compiler used to compile the classes. Thus, you have to compile from an equivalent environment for the hash to match.
Finally, this doesn't cope with the fact that a zip file might itself contain other zip files. While it would be straight forward enough to make the inspection cater for this and descend into nested zip/jar/war files, our implementation does not.
Related
This question already has answers here:
How to list the files inside a JAR file?
(17 answers)
Closed 1 year ago.
This method does not apply:
Files.walk(Paths.get("folder name"))
Because when the app is running, packaged as a jar, it does not contain File objects.
Is there a method for an app to walk through all the contents of one of its packages while it runs?
There is; open the jar file (using java.io.JarFile) and walk through the entries returned by entries(). There's also JarInputStream if your jar is being streamed in from elsewhere.
But, it sounds like you have equated 'jar file' with 'my application, at runtime'.
That's a tricky move. For starters, figuring out your own jar is possible but a little hacky, and more importantly, it then means your app straight up fails to work unless it is in jar form. This complicates deployment, development, and debugging.
There is no need to do it this way.
You can ask java for resources from 'whereever it is currently picking up class files'. A class file is a resource crucial to the running of your application. So is e.g. an icon file for a GUI app. Both should be coming from the same place, and where that is? That's abstracted away, and you should follow along with the abstraction, so that the 'load resource' code works just as well in debugging as it does at runtime.
The system for this is MyClass.class.getResource("file.txt") which will look for file.txt in the same place MyClass.class is located, even if it is in jar files, generated live, or obtained from a BLOB object in a database someplace, or streamed over a network.
The downside is, this system does not have an abstraction for listing files. Only for getting resources with a specific name.
The SPI system is the solution: Make a file that lists (one resource per line) the resources - instead of 'list dir', you 'parse each line of CONTENTS.txt' for the equivalent operation. You can then use annotation processors, if you must, to automatically create and maintain this content file.
ServiceLoader is baked into the JDK itself, but it's designed to load, specifically, class files and not other resources. But the principle is trivial and can be handwritten in about 5 lines of code.
You can iterate the contents of any ZIP / JAR file using Files / NIO, but you need to access the ZIP filesystem. Then you can call Files.find or Files.walk on the contents of the ZIP / JAR archive.
For example this will print the contents of every Path in a jar:
Path zip = Path.of("your.jar");
BiPredicate<Path, BasicFileAttributes> predicate = (p,a) -> true;
try (FileSystem fs = FileSystems.newFileSystem(zip)) {
for (Path root : fs.getRootDirectories()) {
try(Stream<Path> stream = Files.find(root, Integer.MAX_VALUE, predicate)) {
stream.forEach(System.out::println);
}
}
}
Once you have a Path object from the ZIP FileSystem, you can access the contents of the entries using NIO Files calls in the normal manner such as with Files.newInputStream or Files.copy.
I'm writing a Java program which given a qualified-name (like: java.lang.String), fetches and returns the corresponding entry from the src.zip file in the JDK for further processing.
So far my program works fine for any qualified-name which refers to a specific .java source file; but I'm having trouble when the qualified-name refers to a whole package (like: java.util.*). In this case I want my program to return a listing of all entries in the given package.
The problem is it seems there's no way to (efficiently) do such a thing using the utilities provided in the java.util.zip.* package! I have tried both ZipFile and ZipInputStream and none recognize the directories in the src.zip file! They only return entries for individual .java source files!
In code language, both:
ZipEntry entry;
ZipInputStream zip = new ZipInputStream(new FileInputStream("src.zip"));
while((entry = zip.getNextEntry()) != null)
System.out.println(entry.isDirectory());
and:
Enumeration<? extends ZipEntry> zip = new ZipFile("src.zip").entries();
while (zip.hasMoreElements()) {
ZipEntry entry = zip.nextElement();
System.out.println(entry.isDirectory());
}
always return false; no directories at all!
Even the following code is useless and just returns null (which means Not Found):
ZipFile zipfile = new ZipFile("src.zip");
zipfile.getEntry("java/util/");
A work-around is to use either of the two iterations I listed above and perform an exhaustive search for the desired entries:
if (entry.getName().startsWith("java/util/"))
System.out.println(entry);
But clearly this is not efficient! Is there no way to either retrieve the entry of a directory in the src.zip file or to efficiently list the entries for a given directory path? Note that I want to directly process the ZIP file without extraction (for obvious reasons).
Update
As it's apparent from the discussion under Timothy Truckle's answer, the above results were achieved using the src.zip file from the latest Oracle JDK at the time of this writing (i.e. JDK-8 update-111). The results differ when using another src.zip file from a different JDK version (e.g. JDK-7 update-80). The credit goes to marabu for pointing out the unzip -l utility in the comments.
Note
While the problem of retrieving directory entries is solved, the problem of efficiently retrieving the list of entries contained inside a given directory path of a ZIP file is not solved. Yet the case is still closed, since according to Timothy Truckle's answer, this cannot be done in any other way than an exhaustive search in the entries, due to limitations of the ZIP format.
#RC. So your saying that it's related to this specific src.zip file? Because I've seen other ZIP files which do have entries for directories. – Seyed Mohammad
No and Yes. The ZIP file format does only know of files but not directories.
What you may have seen in other zip files is that they included a zero length file named . for each (sub-) folder. But it is not required nor default to do so.
But even if this special entries exist you could not handle them as folders within the ZIP directly (even that all files in the same subfolder are listed consecutively is by accident and neither required nor implied).
I have combined two files in android, using this Linux command
cat file1.png file2.zip > file3.png
How can I split two files again?I just want the zip file to be retrieved separately.
Is there any specific command?I've tried these codes:
unzip file3.png
Replaced png with zip:
unzip file3.zip
but none of them work.
The only application with which I can open the combination, is winrar on windows
And also I tried several unzipping and unraring apps on android but none of them work except RAR app by rarlab
Is there any source for those apps I mentioned to unrar/unzip the file?
Strictly speaking : there's no way.
You might look for the PK 0x04 0x03 as a separator in the answer above, but you don't have any guaranty that this char sequence does not show up in the image data of the file1.png as well.
All together it's a funny question. If you want to split files like this on a regular basis rethink your strategy. If you need it to correct a one time mistake or something, you can split finding the seperator and be ok in over 99% of the cases.
What you need to know is that PNG files start with the hex value 0x89 followed by the text PNG. Zip files start with PK 0x04 0x03. You could write a utility which reads a file and outputs the bytes read in to a new file, using a new output file when a certain file signature is detected.
For a one-of solution, you can use vim, though you have to be careful to stop vim from adding a newline character to the end of the line.
Copy your input file for safety
cp file3.png f1
cp file3.png f2
vim -b f1
and in vim type
:set noeol
search for the start of the zip file
/PK
checking that the sequence found is PK^C^D. If not, look for the next match.
Delete the end of the line from PK with
d$
Move down a line, delete the remainder of the file and save
j
:.,$ d
ZZ
Similarly, delete the top of the file in f2 to get the zip file.
Note: don't name f2 as f2.zip because vim is smart enough to open this as as a zip file, which is not what you want here.
I'm not sure what you trying to accomplish by "hiding" a zip file into a PNG, but if you are trying to make a single file Winrar can open, then that's an odd way to do it.
You do not make a .zip (or any other type of archive) file when you cat a file to the either the start or end of a zip file. That simply appends two binary files together.
The reason winrar can open your "combined" binary file is that it most likely recognizes the file headers and can decipher you have 2 files.
I suggest you look into the usage of the zip command, for how to add files to an archive. I quick search shows, for example
zip -rv zipfile.zip newfile.txt
Will add newfile.txt to zipfile.zip.
I have been searching online about Java Jar signing concepts for some time now to understand what is actually happening when one actually signs his/her jar file.I have looked into various articles pertaining to this , however i ended up reading ones with complex jargons which were not simple to understand. It would be really helpful if you can explain the concept in simple terms / provide any reference link.
My prime objective is to reverse engineer a signed jar file (by whatever means , such as editing the class files within the jar at byte-code level ) to convert it into a working , non-error throwing unsigned jar file.
Please guide me if my approach is not right or if the above mentioned process is not possible.
Thanks in advance.
Generally speaking signing includes the following steps:
Create a hash value over the data to be signed
Do a private key operation operation on the hash value
The result ("the signature") can then be verified by anyone who has the public key. Usually the signature is packaged in a data structure that contains the public key and infos about the algorithms that were used for signing.
Signed jar files contain two additional files in the META-INF folder (open the jar file with 7-Zip or whatever file archiver you prefer to see the content), for example:
META-INF/BCKEY.DSA
META-INF/BCKEY.SF
The ".SF" file contains hash values for every file in the jar:
Signature-Version: 1.0
Created-By: 1.5.0_08 (Sun Microsystems Inc.)
SHA1-Digest-Manifest-Main-Attributes: TCwFll9z+7/6t/SlEoKf3a1SEKU=
SHA1-Digest-Manifest: tbYd5vvo/j3yIenDqYs8xdPRv4c=
Name: org/bouncycastle/asn1/ua/DSTU4145BinaryField.class
SHA1-Digest: LwFPLRwMlgwj7TOKYsDtqhS6+lE=
Name: org/bouncycastle/asn1/DEREnumerated.class
SHA1-Digest: DLc3+IOaSG+cgzW+u4KUbgyypWA=
Name: org/bouncycastle/asn1/x509/SubjectKeyIdentifier.class
SHA1-Digest: v08rbVIhc3KGIL/JlpIPqwQTvgI=
...
The ".DSA" file contains the signature and additional information in PKCS#7 format. The file extension depends on the key algorithm (".DSA", ".RSA" or ".EC").
"BCKEY" is just a name for the signature (usually the first 8 characters of the key alias used for signing). There might be several pairs of signature files in the META-INF folder.
The documentation of jarsigner contains a short passage about those files, it is titled "The Signed JAR File".
So, if you want to remove the signature from a jar file, you simply have to delete all ".SF" and ".RSA"/".DSA"/".EC" files.
I have some .cfm files which have a binary corrupted lines, and I used a Java decompiler to see the code of these files by converting its extension to .class.
What I ask about, how can I modify on these files, or even see the lines as a CFML template, and run it so I can access it on my server
����
SourceFile :C:\inetpub\wwwroot\Clients\ent\www\ADMIN\clips\logclip.cfm
To my knowledge there is no way to get the original source back from the compiled cfm files because it is not actually encrypted or corrupted, it's really just a class file.
There is a bit more information about it here by Rupesh Kumar from the CF team
http://coldfused.blogspot.co.uk/2008/01/encrypted-cfml-templates.html
2 answers here:
If you are speaking of the compiled class files and you have the cfm files you can safely delete the classfiles (in the "cfclasses" directory of your instance). ColdFusion will recompile them when next your run the source file. The big gotcha is, if this is a high traffic site and you delete ALL the files, then you may drag your server down as CF has to recompile everything. In that case you might want to be more selective.
If you mean you are seeing nonsense encryption in a CF file and the only readible part of the file is at the top (a sort of header that tells you what it is), then you are working with encrypted CFM files - CF provides (or provided) a utility to encrypt and deploy CFM files to hide source code. The CF engine can unecrypt these files into regular CF then compile them down into class files. The encryption used was (in the past) quite trivial and not much protection at all. I have unecrypted these files in the past for site owners who owned their code but whose developer had chosen to encrypt them and not provide source copies.
YOu can find methods to unecrypt them (and even utilities to do it) in the wild if this is your issue. My only caution would be be sure you have a right to the code - there was a time when many devs sold encrypted custom tags and widgets - encrypted to prevent them from propogating without license.