Go中的iOS游戏中心身份验证

时间:2014-01-08 23:33:19

标签: ios iphone ios7 go game-center

我正在尝试在Go中编写一个服务,该服务采用GameCenter在

中给出的参数
//GKLocalPlayer
- (void)generateIdentityVerificationSignatureWithCompletionHandler:(void (^)(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error))completionHandler

在方法的completionHandler内,我将公共密钥URL,base 64编码签名,base 64编码盐,时间戳和用户的游戏中心ID发送到我的Go服务。在我的Go(在Google App Engine中),这就是我正在做的事情:

  • 从公钥URL获取证书
  • 解码签名和盐
  • 根据玩家ID,包ID,时间戳和形成有效负载 盐
  • 使用X509.CheckSignature验证有效负载是否匹配 用公钥哄骗的签名

*我知道我仍然需要与证书颁发机构进行验证,但我现在正在跳过(如果您知道如何在Go中执行此操作,请分享!)

问题:CheckSignature正在返回crypto/rsa: verification error我真的认为我按照Apple的指示做了一切

https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40009587-CH1-SW25

到目前为止我的代码:

func (v *ValidationRequest) ValidateGameCenter(publicKeyUrl string, playerId string, bundleId string, signature string, salt string, timestamp uint64) error {
    client := urlfetch.Client(v.Context)

    resp, err := client.Get(publicKeyUrl)
    if err != nil {
        v.Context.Errorf("%v", err.Error())
        return err
    }

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        v.Context.Errorf("%v", err.Error())
        return err
    }

    cert, err := x509.ParseCertificate(body)
    if err != nil {
        v.Context.Errorf("%v", err.Error())
        return err
    }

    signatureBytes, err := base64.StdEncoding.DecodeString(signature)
    saltBytes, err:= base64.StdEncoding.DecodeString(salt)

    payload, err := formPayload(v, playerId, bundleId, timestamp, saltBytes)
    if err != nil {
        v.Context.Errorf("%v", err.Error())
        return err
    }

    err = cert.CheckSignature(cert.SignatureAlgorithm, payload, signatureBytes)
    if err != nil {
        v.Context.Errorf("%v", err.Error())
        return err
    }

    return nil
}

func formPayload(v *ValidationRequest, playerId string, bundleId string, timestamp uint64, salt []byte) ([]byte, error) {
    bundleIdBytes := []byte(bundleId)
    playerIdBytes := []byte(playerId)

    payloadBuffer := new(bytes.Buffer)

    written, err := payloadBuffer.Write(playerIdBytes)
    if err != nil {
        return nil, err
    }

    written, err = payloadBuffer.Write(bundleIdBytes)

    if err != nil {
        return nil, err
    }

    var bigEndianTimestamp []byte = make([]byte, 8)
    binary.BigEndian.PutUint64(bigEndianTimestamp, timestamp)


    if written != len(bundleIdBytes) {
        return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(bundleIdBytes)))
    }

    written, err = payloadBuffer.Write(bigEndianTimestamp)

    if err != nil {
        return nil, err
    }
    if written != len(bigEndianTimestamp) {
        return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(bigEndianTimestamp)))
    }

    written, err = payloadBuffer.Write(salt)
    if err != nil {
        return nil, err
    }

    if written != len(salt) {
        return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(salt)))
    }

    return payloadBuffer.Bytes(), nil
}

0 个答案:

没有答案