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!
问题:
回答1:
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.