calculate signature of classes.dex in android - java

i want to calculate the signature of classes.dex and
something like this
public byte[] computeSignature() throws IOException {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new AssertionError();
}
byte[] buffer = new byte[8192];
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
data.limit(data.capacity());
data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);
while (data.hasRemaining()) {
int count = Math.min(buffer.length, data.remaining());
data.get(buffer, 0, count);
digest.update(buffer, 0, count);
}
return digest.digest();
}
but im confused
any help with proper code ?

Related

Inconsistent output of zip functions between Python and Java methods

I'm integrating my system with external one.
My system is written in Java when external is writen in Python.
This system requires to compress body of request before sending it.
Below are functions used for compression:
def decompress(input_bytes):
bytes = input_bytes.encode('utf-8')
deflate_byte = base64.decodebytes(bytes)
output = zlib.decompress(deflate_byte)
out_str = output.decode('utf-8')
return out_str
def compress(input_str):
input_bytes = input_str.encode('utf-8')
compress = zlib.compress(input_bytes)
output_bytes = base64.encodebytes(compress)
out_str = output_bytes.decode('utf-8')
return out_str
I have developed code for compression/decompression in Java:
public byte[] compress(String str) {
byte[] data = str.getBytes(UTF_8);
Deflater deflater = new Deflater();
deflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
deflater.finish();
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buffer); // returns the generated code... index
outputStream.write(buffer, 0, count);
}
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
byte[] output = outputStream.toByteArray();
return Base64.decodeBase64(output);
}
#Override
public String decompress(byte[] data) {
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = 0;
try {
count = inflater.inflate(buffer);
} catch (DataFormatException e) {
throw new RuntimeException(e);
}
outputStream.write(buffer, 0, count);
}
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
byte[] output = outputStream.toByteArray();
return new String(output);
}
But the output of compression methods is incompatible:
Input:
test
Output of compression implemented in Python:
eJwrSS0uAQAEXQHB
Output of compression implemented in Java:
��>
I would be grateful for explanation of that difference and help how to get in Java solution that is equivalent to those Python methods.
Thank you in advance.

BadPaddingException with decryption using AES algorithm java

I was trying to do encryption of videos and pdf. After i get the stream of each file, i divided into buffers, then i encrypt each one and combine all buffers into one encrypted file.
For encryption everything works fine but when i am trying to decrypt the file by the same way I am getting error at doFinal which is
{BadPaddingException : pad block corrupted
BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)}
here is the code I am testing
Encryption
public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(fileData);
return encrypted;
}
Decryption
public static byte[] decodeFile(byte[] key, byte[] fileData)
{
byte[] decrypted=new byte[0];
try {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted= cipher.doFinal(fileData);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
return decrypted;
}
Generate key
public static byte[] generateKey(String password) throws Exception
{
byte[] keyStart = password.getBytes("UTF-8");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(keyStart);
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
here is how i decrypt the file
public void decryptStream(String filePath) {
String outPath = Environment.getExternalStorageDirectory().toString() + "/" + fileName + "de" + "." + fileExtention;
filePath += "_secured." + fileExtention;
byte[] data = new byte[1024];
byte[] decryptData;
File file = new File((filePath));
File deFile = new File(outPath);
InputStream inputStream = null;
try {
inputStream = FileUtils.openInputStream(file);
} catch (IOException e) {
e.printStackTrace();
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream((new FileOutputStream(deFile)));
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte[] decryptByteArray(byte[] input) {
Encryption e=new Encryption();
byte[]decryptedBytes = new byte[0];
try {
byte[] yourKey = e.generateKey("password");
decryptedBytes = e.decodeFile(yourKey, input);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
return decryptedBytes;
}
The problem is most likely here:
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
When you read a file that is not a multiple of 1024 bytes long, the last read will not completely fill the byte array but you pass the whole array into decryptByteArray.
Also note, that there is no guarantee that read will fill the array completely even for intermediate reads. Always check the return value which gives the number of bytes actually read.
The question does not show how the encryption is done. If padding is used in the cipher, each encryption of a 1024 byte chunk will be longer than 1024 bytes (because of the added padding block). For decryption the whole ciphertext (including the padding) must be processed in one go. Just using the first 1024 bytes will lead to the BadPaddingException.

md5 checksum on file in android doesn't match the md5 after i email it to myself

The functions I'm using to convert the file to a string and then to an mdf are below. I'm outputting the file paths and file names to make sure everything is cool. Is there anything I'm not considering that could change the file's (a video mp4 actually) fingerprint? I'm checking it against md5sum on ubuntu.
private static String readFileToString(String filePath)
throws java.io.IOException{
StringBuffer fileData = new StringBuffer(1000);
BufferedReader reader = new BufferedReader(
new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
System.out.println(fileData.toString());
return fileData.toString();
}
public static String getMD5EncryptedString(String encTarget){
MessageDigest mdEnc = null;
try {
mdEnc = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
System.out.println("Exception while encrypting to md5");
e.printStackTrace();
} // Encryption algorithm
mdEnc.update(encTarget.getBytes(), 0, encTarget.length());
String md5 = new BigInteger(1, mdEnc.digest()).toString(16) ;
return md5;
}
String isn't a container for binary data. Lose the two conversions between byte array and String. You should be reading the file as bytes and computing the MD5 directly in the bytes. You can do that while you're reading it: you don't need to read the entire file first.
And MD5 isn't an encryption: it's a secure hash.
Found this answer here: How to generate an MD5 checksum for a file in Android?
public static String fileToMD5(String filePath) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
MessageDigest digest = MessageDigest.getInstance("MD5");
int numRead = 0;
while (numRead != -1) {
numRead = inputStream.read(buffer);
if (numRead > 0)
digest.update(buffer, 0, numRead);
}
byte [] md5Bytes = digest.digest();
return convertHashToString(md5Bytes);
} catch (Exception e) {
return null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) { }
}
}
}
private static String convertHashToString(byte[] md5Bytes) {
String returnVal = "";
for (int i = 0; i < md5Bytes.length; i++) {
returnVal += Integer.toString(( md5Bytes[i] & 0xff ) + 0x100, 16).substring(1);
}
return returnVal;
}

RSA encryption in Java

I am trying to write an encryption algorithm using RSA in Java, I am getting a
"javax.crypto.BadPaddingException: Data must start with zero"; I do not know what is this exception for.
This is the example I used here
and Here is my code; please help.
public byte[] getEncryptedValue(byte[] bytes, PublicKey key) {
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
return blockCipher(bytes, Cipher.ENCRYPT_MODE);
} catch (Exception ex) {
Logger.getLogger(SecurityUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public byte[] getDecryptedValue(byte[] bytes, PrivateKey key) {
try {
cipher.init(Cipher.DECRYPT_MODE, key);
return blockCipher(bytes, Cipher.DECRYPT_MODE);
} catch (Exception ex) {
Logger.getLogger(SecurityUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private byte[] append(byte[] prefix, byte[] suffix) {
byte[] toReturn = new byte[prefix.length + suffix.length];
System.arraycopy(prefix, 0, toReturn, 0, prefix.length);
System.arraycopy(suffix, 0, toReturn, prefix.length, suffix.length);
return toReturn;
}
private byte[] blockCipher(byte[] bytes, int mode) throws IllegalBlockSizeException, BadPaddingException {
byte[] scrambled = new byte[0];
byte[] toReturn = new byte[0];blocks (because of RSA)
int length = (mode == Cipher.ENCRYPT_MODE) ? 100 : 128;
int n = 0;
byte[] buffer = new byte[length];
for (int i = 0; i < bytes.length; i++) {
if ((i > 0) && (i % length == 0)) {
n = 0;
scrambled = cipher.doFinal(buffer);
toReturn = append(toReturn, scrambled);
}
buffer[i % length] = bytes[i];
n++;
}
***scrambled = cipher.doFinal(buffer, 0, n);*** <-- the exception is caught here
toReturn = append(toReturn, scrambled);
return toReturn;
}
The problem could be the data sent over the network using sockets may be corrupted due to some encoding problems. I had the same problem while developing a simple client/server chat program that encrypts/decrypts using asymmetric key the messages between the server and client and vise versa, instead of sending the message as a string, I sent it as a byte array which is the encrypted message.
check if keys are matching
check if data returned by getEncryptedValue are the same that you pass to getDecryptedValue
check corectness of loop in blockCipher method

Calculate md5 hash of a zip file in Java program

I have a zip file, and in my Java code i want to calculate the md5 hash of the zip file. Is there any java libary i can use for this purpose ?. Some example would be really appreciated.
Thank You
I got that working a few weeks ago with this Article here:
http://www.javalobby.org/java/forums/t84420.html
Just to have it a stackoveflow:
public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException {
MessageDigest digest = MessageDigest.getInstance("MD5");
File f = new File("c:\\myfile.txt");
InputStream is = new FileInputStream(f);
byte[] buffer = new byte[8192];
int read = 0;
try {
while( (read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
String output = bigInt.toString(16);
System.out.println("MD5: " + output);
}
catch(IOException e) {
throw new RuntimeException("Unable to process file for MD5", e);
}
finally {
try {
is.close();
}
catch(IOException e) {
throw new RuntimeException("Unable to close input stream for MD5 calculation", e);
}
}
}
There is also an option to do that with Apache Codec like that
final String sha256 = DigestUtils.sha256Hex(new FileInputStream(file))

Categories

Resources