diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-01-30 17:24:35 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-01-30 17:24:35 +0100 |
commit | 472da7425e8ce6bdb55d54af4bdbcfb5a2732b99 (patch) | |
tree | 4a69c79c6dd93ad0706ce70777dcad4059688212 /util | |
parent | 8325a033326725fcf193f0dae9c04e45c5ec5f97 (diff) | |
download | libeufin-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.kt | 5 | ||||
-rw-r--r-- | util/src/main/kotlin/strings.kt | 31 | ||||
-rw-r--r-- | util/src/test/kotlin/CryptoUtilTest.kt | 47 |
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 |