mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Better binary hash implementation
This commit is contained in:
@@ -42,7 +42,7 @@ class BinaryFileTest {
|
||||
saveBinary(TEST_TEXT_ASSET, binaryA)
|
||||
saveBinary(TEST_TEXT_ASSET, binaryB)
|
||||
assertEquals("Save text binary length failed.", binaryA.length, binaryB.length)
|
||||
assertEquals("Save text binary MD5 failed.", binaryA.md5(), binaryB.md5())
|
||||
assertEquals("Save text binary MD5 failed.", binaryA.binaryHash(), binaryB.binaryHash())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -52,7 +52,7 @@ class BinaryFileTest {
|
||||
saveBinary(TEST_IMAGE_ASSET, binaryA)
|
||||
saveBinary(TEST_IMAGE_ASSET, binaryB)
|
||||
assertEquals("Save image binary length failed.", binaryA.length, binaryB.length)
|
||||
assertEquals("Save image binary failed.", binaryA.md5(), binaryB.md5())
|
||||
assertEquals("Save image binary failed.", binaryA.binaryHash(), binaryB.binaryHash())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -66,10 +66,10 @@ class BinaryFileTest {
|
||||
binaryA.compress(loadedKey)
|
||||
binaryB.compress(loadedKey)
|
||||
assertEquals("Compress text length failed.", binaryA.length, binaryB.length)
|
||||
assertEquals("Compress text MD5 failed.", binaryA.md5(), binaryB.md5())
|
||||
assertEquals("Compress text MD5 failed.", binaryA.binaryHash(), binaryB.binaryHash())
|
||||
binaryB.decompress(loadedKey)
|
||||
assertEquals("Decompress text length failed.", binaryB.length, binaryC.length)
|
||||
assertEquals("Decompress text MD5 failed.", binaryB.md5(), binaryC.md5())
|
||||
assertEquals("Decompress text MD5 failed.", binaryB.binaryHash(), binaryC.binaryHash())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,11 +83,11 @@ class BinaryFileTest {
|
||||
binaryA.compress(loadedKey)
|
||||
binaryB.compress(loadedKey)
|
||||
assertEquals("Compress image length failed.", binaryA.length, binaryA.length)
|
||||
assertEquals("Compress image failed.", binaryA.md5(), binaryA.md5())
|
||||
assertEquals("Compress image failed.", binaryA.binaryHash(), binaryA.binaryHash())
|
||||
binaryB = BinaryFile(fileB, true)
|
||||
binaryB.decompress(loadedKey)
|
||||
assertEquals("Decompress image length failed.", binaryB.length, binaryC.length)
|
||||
assertEquals("Decompress image failed.", binaryB.md5(), binaryC.md5())
|
||||
assertEquals("Decompress image failed.", binaryB.binaryHash(), binaryC.binaryHash())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.stream.readAllBytes
|
||||
import org.apache.commons.io.output.CountingOutputStream
|
||||
import java.io.*
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.MessageDigest
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
@@ -41,6 +42,7 @@ class BinaryFile : Parcelable {
|
||||
private var dataFile: File? = null
|
||||
var length: Long = 0
|
||||
private set
|
||||
private var mBinaryHash = 0
|
||||
var isCompressed: Boolean = false
|
||||
private set
|
||||
var isProtected: Boolean = false
|
||||
@@ -182,23 +184,11 @@ class BinaryFile : Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 of the raw encrypted file in temp folder, only to compare binary data
|
||||
* Hash of the raw encrypted file in temp folder, only to compare binary data
|
||||
*/
|
||||
@Throws(FileNotFoundException::class)
|
||||
fun md5(): String {
|
||||
val md = MessageDigest.getInstance("MD5")
|
||||
if (dataFile == null)
|
||||
return ""
|
||||
return FileInputStream(dataFile).use { fis ->
|
||||
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
||||
generateSequence {
|
||||
when (val bytesRead = fis.read(buffer)) {
|
||||
-1 -> null
|
||||
else -> bytesRead
|
||||
}
|
||||
}.forEach { bytesRead -> md.update(buffer, 0, bytesRead) }
|
||||
md.digest().joinToString("") { "%02x".format(it) }
|
||||
}
|
||||
fun binaryHash(): Int {
|
||||
return mBinaryHash
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
@@ -247,11 +237,15 @@ class BinaryFile : Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom OutputStream to calculate the size of binary file
|
||||
* Custom OutputStream to calculate the size and hash of binary file
|
||||
*/
|
||||
private inner class BinaryCountingOutputStream(out: OutputStream): CountingOutputStream(out) {
|
||||
|
||||
private val mMessageDigest: MessageDigest
|
||||
init {
|
||||
length = 0
|
||||
mMessageDigest = MessageDigest.getInstance("MD5")
|
||||
mBinaryHash = 0
|
||||
}
|
||||
|
||||
override fun beforeWrite(n: Int) {
|
||||
@@ -259,9 +253,26 @@ class BinaryFile : Parcelable {
|
||||
length = byteCount
|
||||
}
|
||||
|
||||
override fun write(idx: Int) {
|
||||
super.write(idx)
|
||||
mMessageDigest.update(idx.toByte())
|
||||
}
|
||||
|
||||
override fun write(bts: ByteArray) {
|
||||
super.write(bts)
|
||||
mMessageDigest.update(bts)
|
||||
}
|
||||
|
||||
override fun write(bts: ByteArray, st: Int, end: Int) {
|
||||
super.write(bts, st, end)
|
||||
mMessageDigest.update(bts, st, end)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
super.close()
|
||||
length = byteCount
|
||||
val bytes = mMessageDigest.digest()
|
||||
mBinaryHash = ByteBuffer.wrap(bytes).int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,10 +125,10 @@ abstract class BinaryPool<T> {
|
||||
try {
|
||||
binaryFile?.let {
|
||||
if (it.length > 0) {
|
||||
val searchBinaryMD5 = it.md5()
|
||||
val searchBinaryMD5 = it.binaryHash()
|
||||
var i = 0
|
||||
for ((_, binary) in pool) {
|
||||
if (binary.md5() == searchBinaryMD5) {
|
||||
if (binary.binaryHash() == searchBinaryMD5) {
|
||||
i++
|
||||
if (i > 1)
|
||||
return true
|
||||
@@ -169,12 +169,16 @@ abstract class BinaryPool<T> {
|
||||
val existentBinary =
|
||||
try {
|
||||
if (binary.length > 0) {
|
||||
keyBinaryList.find { it.binary.md5() == binary.md5() }
|
||||
keyBinaryList.find {
|
||||
val hash0 = it.binary.binaryHash()
|
||||
val hash1 = binary.binaryHash()
|
||||
hash0 != 0 && hash1 != 0 && hash0 == hash1
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to check binary MD5", e)
|
||||
Log.e(TAG, "Unable to check binary hash", e)
|
||||
null
|
||||
}
|
||||
if (existentBinary == null) {
|
||||
|
||||
Reference in New Issue
Block a user