1

In android I am using the following code to generate KeyPair

 fun generateKeyPair(): KeyPair {
            val keyGen = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider())
            val ecSpec = ECGenParameterSpec("prime256v1")
            val random = SecureRandom.getInstance("SHA1PRNG")
            keyGen.initialize(ecSpec,random)
            return keyGen.generateKeyPair()
}

and it returns KeyPair, after converting to hex I am getting

public:3059301306072A8648CE3D020106082A8648CE3D03010703420004CF2245EC08585CBDE04CB10AA4D33A4C5AED224D28AA6A6AB840DE694C0DE1F73064922D6759D424B04E34DDA0885FE2C80FE80DC44F4BB5579E515519B66583

private:308193020100301306072A8648CE3D020106082A8648CE3D030107047930770201010420A7BAA38400D1AF60B203C49B378296FF3A7D1989A05A7BE55C0C9E04516CF183A00A06082A8648CE3D030107A14403420004CF2245EC08585CBDE04CB10AA4D33A4C5AED224D28AA6A6AB840DE694C0DE1F73064922D6759D424B04E34DDA0885FE2C80FE80DC44F4BB5579E515519B66583

 @Throws(NoSuchAlgorithmException::class, InvalidKeySpecException::class)
        fun getPublicKey(pk: ByteArray?): PublicKey {
            val publicKeySpec: EncodedKeySpec = X509EncodedKeySpec(pk)
            val kf = KeyFactory.getInstance(KeyProperties.KEY_ALGORITHM_EC)
            return kf.generatePublic(publicKeySpec)
        }



fun hexStringToByteArray(hexString: String): ByteArray? {
        val bytes = ByteArray(hexString.length / 2)
        var i = 0
        while (i < hexString.length) {
            val sub = hexString.substring(i, i + 2)
            val intVal = sub.toInt(16)
            bytes[i / 2] = intVal.toByte()
            val hex = String.format("0x%x", bytes[i / 2])
            i += 2
        }
        return bytes
    }
    fun bytesToHex(bytes: ByteArray): String {
        val HEX_ARRAY = "0123456789ABCDEF".toCharArray()
        val hexChars = CharArray(bytes.size * 2)
        for (j in bytes.indices) {
            val v = bytes[j].toInt() and 0xFF // Here is the conversion
            hexChars[j * 2] = HEX_ARRAY[v.ushr(4)]
            hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F]
        }
        return String(hexChars)
    }

and I am able to generate shared secret also

 val keyAgreement = KeyAgreement.getInstance("ECDH", BouncyCastleProvider())
                keyAgreement.init(private)
                keyAgreement.doPhase(getPublicKey(hexStringToByteArray("3059301306072A8648CE3D020106082A8648CE3D030107034200046E69A6A17934F61F7A601262F66A0414BE8BCF9D7DE423A929A5A0EF6D4C0D1597C3CFBE6C16E8236F245FAE0D7793A225D6E1CD3C0E3830C4E11C8E120848E2")), true)
                val sharedSecret = keyAgreement.generateSecret()
          val secretHex = bytesToHex(sharedSecret)

shared secret 5AA6C5095C8D89C6A9C16C71047E38090EDB90CE3A94B70359B325992B2DCC68

Now coming to iOS using same prime256v1 I am getting following data

private:62f24e3927aa953ae0d6f851b403481387aecd4ceb192eb1065a5897a9971d6d public:b4a7002c6bfb9f1d0fc6fb6a85681c8c2f44a36ad671f5033a1fcb9e49e8709d00c53e45bcf0c46aa948deea1a0f3103c1924713e9e9fd4a9a365d23b395ddc0

Now here comes a difference that is actually I don't understand, and on using public key generated from iOS to generate shared secret in android I am getting error and error on iOS using public key generated from android

Umar Ata
  • 4,170
  • 3
  • 23
  • 35
  • Your question is not clear. How did you test in the first hand and how did it fails actually? If you generate a new key, it will be different. – kelalaka Dec 12 '21 at 20:10
  • @kelalaka my question is simple, why generating KeyPair for prime256v1 is different in length in iOS & Android, and if I generate two pairs in android then I am able to generate shared secret but I am unable to generate shared secret from iOS public key with Android private key and vice versa – Umar Ata Dec 12 '21 at 20:21
  • how did you select the curve in iOS? Also, how do you transfer the data? Are you sure it is not corrupted on the way? – kelalaka Dec 12 '21 at 20:24
  • using below code in iOS let privateKey = P256.KeyAgreement.PrivateKey() the hex you see above in android is converted to bytes array then converted to public and private key without any error – Umar Ata Dec 12 '21 at 20:30
  • using library in iOS https://github.com/iosdevzone/IDZSwiftCommonCrypto @kelalaka – Umar Ata Dec 12 '21 at 20:32
  • Are you sure that your hex encoding is perfect? the first one should start with `04` and the second one with `03` or `02` due to [point compression](https://crypto.stackexchange.com/a/83468/18298) You should not omit the leading zeros and be careful on endianness – kelalaka Dec 12 '21 at 20:37
  • [https://stackoverflow.com/questions/2817752/java-code-to-convert-byte-to-hexadecimal](https://stackoverflow.com/q/2817752/1820553) – kelalaka Dec 12 '21 at 20:41
  • It will be good if you write a code/function that solves my problem @kelalaka – Umar Ata Dec 12 '21 at 20:41
  • Nowadays, I usually indicate the problems. Not much into coding to solve. – kelalaka Dec 12 '21 at 20:43
  • I tried using org.bouncycastle.util.encoders.Hex.toHexString(private.encoded) and same for public key but getting same length output I am also able to generate public/private key from hex I generated in android so that means my hex is correct otherwise it will not get converted to keys @kelalaka – Umar Ata Dec 12 '21 at 20:52

0 Answers0