summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-01-30 17:24:35 +0100
committerFlorian Dold <florian.dold@gmail.com>2020-01-30 17:24:35 +0100
commit472da7425e8ce6bdb55d54af4bdbcfb5a2732b99 (patch)
tree4a69c79c6dd93ad0706ce70777dcad4059688212 /util
parent8325a033326725fcf193f0dae9c04e45c5ec5f97 (diff)
downloadlibeufin-472da7425e8ce6bdb55d54af4bdbcfb5a2732b99.tar.gz
libeufin-472da7425e8ce6bdb55d54af4bdbcfb5a2732b99.tar.bz2
libeufin-472da7425e8ce6bdb55d54af4bdbcfb5a2732b99.zip
fix hashing with test case
Diffstat (limited to 'util')
-rw-r--r--util/src/main/kotlin/CryptoUtil.kt5
-rw-r--r--util/src/main/kotlin/strings.kt31
-rw-r--r--util/src/test/kotlin/CryptoUtilTest.kt47
3 files changed, 77 insertions, 6 deletions
diff --git a/util/src/main/kotlin/CryptoUtil.kt b/util/src/main/kotlin/CryptoUtil.kt
index e14cf673..65798cf9 100644
--- a/util/src/main/kotlin/CryptoUtil.kt
+++ b/util/src/main/kotlin/CryptoUtil.kt
@@ -121,9 +121,10 @@ object CryptoUtil {
*/
fun getEbicsPublicKeyHash(publicKey: RSAPublicKey): ByteArray {
val keyBytes = ByteArrayOutputStream()
- keyBytes.writeBytes(publicKey.publicExponent.toUnsignedHexString().toByteArray())
+ keyBytes.writeBytes(publicKey.publicExponent.toUnsignedHexString().toLowerCase().trimStart('0').toByteArray())
keyBytes.write(' '.toInt())
- keyBytes.writeBytes(publicKey.modulus.toUnsignedHexString().toByteArray())
+ keyBytes.writeBytes(publicKey.modulus.toUnsignedHexString().toLowerCase().trimStart('0').toByteArray())
+ println("buffer before hashing: '${keyBytes.toString(Charsets.UTF_8)}'")
val digest = MessageDigest.getInstance("SHA-256")
return digest.digest(keyBytes.toByteArray())
}
diff --git a/util/src/main/kotlin/strings.kt b/util/src/main/kotlin/strings.kt
index b113e06a..d8d5b8d4 100644
--- a/util/src/main/kotlin/strings.kt
+++ b/util/src/main/kotlin/strings.kt
@@ -5,10 +5,34 @@ import java.util.*
fun ByteArray.toHexString() : String {
return this.joinToString("") {
- java.lang.String.format("%02x", it)
+ java.lang.String.format("%02X", it)
}
}
+private fun toDigit(hexChar: Char): Int {
+ val digit = Character.digit(hexChar, 16)
+ require(digit != -1) { "Invalid Hexadecimal Character: $hexChar" }
+ return digit
+}
+
+private fun hexToByte(hexString: String): Byte {
+ val firstDigit: Int = toDigit(hexString[0])
+ val secondDigit: Int = toDigit(hexString[1])
+ return ((firstDigit shl 4) + secondDigit).toByte()
+}
+
+fun decodeHexString(hexString: String): ByteArray {
+ val hs = hexString.replace(" ", "").replace("\n", "")
+ require(hs.length % 2 != 1) { "Invalid hexadecimal String supplied." }
+ val bytes = ByteArray(hs.length / 2)
+ var i = 0
+ while (i < hs.length) {
+ bytes[i / 2] = hexToByte(hs.substring(i, i + 2))
+ i += 2
+ }
+ return bytes
+}
+
fun bytesToBase64(bytes: ByteArray): String {
return Base64.getEncoder().encodeToString(bytes)
}
@@ -19,7 +43,8 @@ fun base64ToBytes(encoding: String): ByteArray {
fun BigInteger.toUnsignedHexString(): String {
val signedValue = this.toByteArray()
- require(signedValue[0] == 0.toByte()) { "value must be a positive BigInteger" }
- val bytes = Arrays.copyOfRange(signedValue, 1, signedValue.size)
+ require(this.signum() > 0) { "number must be positive"}
+ val start = if (signedValue[0] == 0.toByte()) { 1 } else { 0 }
+ val bytes = Arrays.copyOfRange(signedValue, start, signedValue.size)
return bytes.toHexString()
} \ No newline at end of file
diff --git a/util/src/test/kotlin/CryptoUtilTest.kt b/util/src/test/kotlin/CryptoUtilTest.kt
index 9422a91b..a64a9423 100644
--- a/util/src/test/kotlin/CryptoUtilTest.kt
+++ b/util/src/test/kotlin/CryptoUtilTest.kt
@@ -19,6 +19,10 @@
import org.junit.Test
import tech.libeufin.util.CryptoUtil
+import tech.libeufin.util.decodeHexString
+import tech.libeufin.util.toHexString
+import tech.libeufin.util.toUnsignedHexString
+import java.math.BigInteger
import java.security.KeyPairGenerator
import java.security.interfaces.RSAPrivateCrtKey
import javax.crypto.EncryptedPrivateKeyInfo
@@ -85,7 +89,7 @@ class CryptoUtilTest {
/* encrypt and decrypt private key */
val encPriv = CryptoUtil.encryptKey(keyPair.private.encoded, "secret")
- val plainPriv = CryptoUtil.decryptKey(EncryptedPrivateKeyInfo(encPriv),"secret")
+ val plainPriv = CryptoUtil.decryptKey(EncryptedPrivateKeyInfo(encPriv), "secret")
/* decrypt with decrypted private key */
val revealed = CryptoUtil.decryptEbicsE002(secret, plainPriv)
@@ -95,4 +99,45 @@ class CryptoUtilTest {
String(data, charset = Charsets.UTF_8)
)
}
+
+ @Test
+ fun testEbicsPublicKeyHashing() {
+ val exponentStr = "01 00 01"
+ val moduloStr = """
+ EB BD B8 E3 73 45 60 06 44 A1 AD 6A 25 33 65 F5
+ 9C EB E5 93 E0 51 72 77 90 6B F0 58 A8 89 EB 00
+ C6 0B 37 38 F3 3C 55 F2 4D 83 D0 33 C3 A8 F0 3C
+ 82 4E AF 78 51 D6 F4 71 6A CC 9C 10 2A 58 C9 5F
+ 3D 30 B4 31 D7 1B 79 6D 43 AA F9 75 B5 7E 0B 4A
+ 55 52 1D 7C AC 8F 92 B0 AE 9F CF 5F 16 5C 6A D1
+ 88 DB E2 48 E7 78 43 F9 18 63 29 45 ED 6C 08 6C
+ 16 1C DE F3 02 01 23 8A 58 35 43 2B 2E C5 3F 6F
+ 33 B7 A3 46 E1 75 BD 98 7C 6D 55 DE 71 11 56 3D
+ 7A 2C 85 42 98 42 DF 94 BF E8 8B 76 84 13 3E CA
+ 0E 8D 12 57 D6 8A CF 82 DE B7 D7 BB BC 45 AE 25
+ 95 76 00 19 08 AA D2 C8 A7 D8 10 37 88 96 B9 98
+ 14 B4 B0 65 F3 36 CE 93 F7 46 12 58 9F E7 79 33
+ D5 BE 0D 0E F8 E7 E0 A9 C3 10 51 A1 3E A4 4F 67
+ 5E 75 8C 9D E6 FE 27 B6 3C CF 61 9B 31 D4 D0 22
+ B9 2E 4C AF 5F D6 4B 1F F0 4D 06 5F 68 EB 0B 71
+ """.trimIndent()
+ val expectedHashStr = """
+ 72 71 D5 83 B4 24 A6 DA 0B 7B 22 24 3B E2 B8 8C
+ 6E A6 0F 9F 76 11 FD 18 BE 2C E8 8B 21 03 A9 41
+ """.trimIndent()
+
+ val expectedHash = expectedHashStr.replace(" ", "").replace("\n", "").toByteArray(Charsets.UTF_8)
+
+ val pub = CryptoUtil.loadRsaPublicKeyFromComponents(decodeHexString(moduloStr), decodeHexString(exponentStr))
+
+ println("echoed pub exp: ${pub.publicExponent.toUnsignedHexString()}")
+ println("echoed pub mod: ${pub.modulus.toUnsignedHexString()}")
+
+ val pubHash = CryptoUtil.getEbicsPublicKeyHash(pub)
+
+ println("our pubHash: ${pubHash.toHexString()}")
+ println("expected pubHash: ${expectedHash.toString(Charsets.UTF_8)}")
+
+ assertEquals(expectedHash.toString(Charsets.UTF_8), pubHash.toHexString())
+ }
} \ No newline at end of file