我正在尝试在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中),这就是我正在做的事情:
*我知道我仍然需要与证书颁发机构进行验证,但我现在正在跳过(如果您知道如何在Go中执行此操作,请分享!)
问题:CheckSignature
正在返回crypto/rsa: verification error
我真的认为我按照Apple的指示做了一切
到目前为止我的代码:
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
}