How to authenticate the GKLocalPlayer on my 'third party server'?

后端 未结 10 441
鱼传尺愫
鱼传尺愫 2020-11-30 02:53

iOS7 introduced new GKLocalPlayer method generateIdentityVerificationSignatureWithCompletionHandler().

Does anyone know how to use it for good? I assum

10条回答
  •  被撕碎了的回忆
    2020-11-30 03:18

    Thanks to those who provided solutions in other languages.

    Here are the relevant bits of solution in Scala (trivial to convert to Java):

    private def verify(
      signatureAlgorithm: String, 
      publicKey: PublicKey, 
      message: Array[Byte], 
      signature: Array[Byte]): Boolean = {
    
      val sha1Signature = Signature.getInstance(signatureAlgorithm)
      sha1Signature.initVerify(publicKey)
      sha1Signature.update(message)
      sha1Signature.verify(signature)
    }
    
    val x509Cert = Try(certificateFactory.generateCertificate(new ByteArrayInputStream(publicKeyBytes)).asInstanceOf[X509Certificate])
    x509Cert.foreach { cert =>
      signatureAlgorithm = Some(cert.getSigAlgName)
    }
    x509Cert.map(_.getPublicKey) match {
      case Success(pk) =>
        log.debug("downloaded public key successfully")
        publicKey = Some(pk)
    }
    
    val buffer = 
      r.id.getBytes("UTF-8") ++ 
      bundleId.getBytes("UTF-8") ++
      ByteBuffer.allocate(8).putLong(r.timestamp).array() ++ 
      Base64.decode(r.salt)
    
    val result = verify(signatureAlgorithm.getOrElse("SHA256withRSA"), pk, buffer, Base64.decode(r.signature))
    
    log.info("verification result {} for request {}", result, r)
    

    where r is an instance of:

    case class IOSIdentityVerificationRequest(
      id: PlayerIdentity, // String
      publicKeyURL: String, 
      signature: String, // base64 encoded bytes
      salt: String, // base64 encoded bytes
      timestamp: Long, 
      error: Option[String]) extends IdentityVerificationRequest
    

提交回复
热议问题