title: ECDSA sign with HSM and verify in Java/Kotlin
body: <p>I have a public key and a signature generated from HSM using CryptokiEx and I need to verify the signature in Java, but have some difficulties doing so.</p>
  
  <p>Signature is signed in HSM</p>
  
  <pre><code>byte[] signature = null;
  LongRef signLen = new LongRef();
  
  CryptokiEx.C_SignInit(hSession, signMech, hPrivateKey);
  
  /* determine the length of the signature */
  CryptokiEx.C_Sign(hSession, hash, hashLen, null, signLen);
  
  signature = new byte[(int) signLen.value];
  
  CryptokiEx.C_Sign(hSession, hash, hashLen, signature, signLen);
  </code></pre>
  
  <p>Output</p>
  
  <pre><code>public key: 030F92CF7082006E46ADBB7C51AD12435110595C59C45518E35C794AD6578D4FEE
  private key: 00BF9044CED80C5E358F3673C998417A564E52B8837C21FD5DA6DFA8E506983B03
  signature: 7531DDE88945CC2431F69C237B7A5A52D042E44CFBE9FF2AC8C821E6EC507EC0ABC6AD1909A7C571E1C504261AEE5B92B3061D9AD7F921738C79806584CFD358
  message hash: 68656c6c6f20776f726c64
  </code></pre>
  
  <p>Public key is constructed</p>
  
  <pre><code>fun constructPublicKey(compressedPKStr: String) :ECPublicKey {
      var publicKeyStr = compressedToUncompressed(compressedPKStr).toHex()
      publicKeyStr = publicKeyStr.substring(2)
      val kf: KeyFactory = KeyFactory.getInstance("EC")
      val pubKeyX = publicKeyStr.substring(0, publicKeyStr.length / 2)
      val pubKeyY = publicKeyStr.substring(publicKeyStr.length / 2)
      val x: ByteArray = pubKeyX.hexToByteArray()
      val y: ByteArray = pubKeyY.hexToByteArray()
      val w = ECPoint(BigInteger(1, x), BigInteger(1, y))
      return kf.generatePublic(ECPublicKeySpec(w, ecParameterSpecForCurve("secp256k1"))) as ECPublicKey
  }
  
  @Throws(NoSuchAlgorithmException::class, InvalidParameterSpecException::class)
  fun ecParameterSpecForCurve(curveName: String?): ECParameterSpec {
      val params = AlgorithmParameters.getInstance("EC")
      params.init(ECGenParameterSpec(curveName))
      return params.getParameterSpec(ECParameterSpec::class.java)
  }
  
  fun compressedToUncompressed(compressedPKStr: String) :ByteArray {
      val compKey = compressedPKStr.hexToByteArray()
      var SPEC = ECNamedCurveTable.getParameterSpec("secp256k1")
      val point = SPEC.curve.decodePoint(compKey)
      val x: ByteArray = point.xCoord.encoded
      val y: ByteArray = point.yCoord.encoded
      // concat 0x04, x, and y, make sure x and y has 32-bytes:
      // 0x04 to indicate uncompressed PK
      return concat(byteArrayOf(0x04), x, y)
  }
  </code></pre>
  
  <p>Signature is converted to ASN.1 DER format</p>
  
  <pre><code>@Throws(NumberFormatException::class)
  fun byteToBin(byte: Byte): String {
      val number = java.lang.Byte.toUnsignedInt(byte)
      val s2 = String.format("%8s", Integer.toBinaryString(number)).replace(' ', '0')
      return s2
  }
  
  fun constructSignature(signatureStr: String) :ByteArray {
      val signatureR = signatureStr.substring(0, signatureStr.length / 2)
      val signatureS = signatureStr.substring(signatureStr.length / 2)
      var signatureRData = signatureR.hexToByteArray()
      val firstRByteBin = byteToBin(signatureRData[0])
      if (firstRByteBin.first() == '1') {
          signatureRData = concat(byteArrayOf(0x00), signatureRData)
      }
      var signatureSData = signatureS.hexToByteArray()
      val firstSByteBin = byteToBin(signatureSData[0])
      if (firstSByteBin.first() == '1') {
          signatureSData = concat(byteArrayOf(0x00), signatureSData)
      }
      val b2 = signatureRData.size
      val b3 = signatureSData.size
      val b1 = b2 + b3 + 4
      return concat(byteArrayOf(0x30, b1.toByte(), 0x02, b2.toByte()), signatureRData, byteArrayOf(0x02, b3.toByte()), signatureSData)
  }
  </code></pre>
  
  <p>Verify the signature but result is false</p>
  
  <pre><code>val testBytes = "68656c6c6f20776f726c64".hexToByteArray()
  
  val publicKeyStr = "030F92CF7082006E46ADBB7C51AD12435110595C59C45518E35C794AD6578D4FEE"
  val publicKey = constructPublicKey(publicKeyStr)
  
  val signatureStr = "7531DDE88945CC2431F69C237B7A5A52D042E44CFBE9FF2AC8C821E6EC507EC0ABC6AD1909A7C571E1C504261AEE5B92B3061D9AD7F921738C79806584CFD358"
  val signatureData = constructSignature(signatureStr)
  
  val signature: Signature = Signature.getInstance("SHA256withECDSA")
  
  signature.initVerify(publicKey)
  
  signature.update(testBytes)
  
  signature.verify(signatureData)
  </code></pre>
  
  <p>Do you have an idea where I am wrong?</p>