Google app engine 如何验证appengine.SignBytes返回的签名?

Google app engine 如何验证appengine.SignBytes返回的签名?,google-app-engine,go,rsa,Google App Engine,Go,Rsa,Google App Engine的Go运行时有一个函数、一个函数和一个结构 func符号字节 SignBytes使用应用程序特有的私钥对字节进行签名 func公共证书 PublicCertificates检索应用程序的公共证书。他们 可用于验证SignBytes返回的签名 类型证书 证书表示应用程序的公共证书 很明显,应用程序需要遍历公共证书来验证签名。但目前尚不清楚签名是如何生成或验证的。Go’s有两个函数来验证签名,和,并且每个函数都使用一个标识符作为参数。目前,有15个不同的散列标识符(

Google App Engine的Go运行时有一个函数、一个函数和一个结构

func符号字节 SignBytes使用应用程序特有的私钥对字节进行签名

func公共证书 PublicCertificates检索应用程序的公共证书。他们 可用于验证SignBytes返回的签名

类型证书 证书表示应用程序的公共证书

很明显,应用程序需要遍历公共证书来验证签名。但目前尚不清楚签名是如何生成或验证的。Go’s有两个函数来验证签名,和,并且每个函数都使用一个标识符作为参数。目前,有15个不同的散列标识符(例如,crypto.MD5、crypto.SHA256),给出2x15=30个验证函数和散列标识符的组合

如何验证SignBytes生成的签名?

使用SHA256验证PKCS1V15 我通过尝试验证方案和散列类型的所有组合发现了这一点;我没有找到文件保证这是将要使用的签名方案

但对于勇敢者来说,下面是一个对数据签名并验证签名的代码示例

package yourpackage

import (
    "crypto"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "errors"
    "google.golang.org/appengine"
    "net/http"
)

func signAndVerify(request *http.Request) error {
    c := appengine.NewContext(request)
    data := []byte("test data to sign")
    _, sig, err := appengine.SignBytes(c, data)
    if err != nil {
        return err
    }

    certs, err := appengine.PublicCertificates(c)
    if err != nil {
        return err
    }

    lastErr := errors.New("ErrNoPublicCertificates")

    for _, cert := range certs {
        block, _ := pem.Decode(cert.Data)
        if block == nil {
            lastErr = errors.New("ErrPemDecodeFailure")
            continue
        }
        x509Cert, err := x509.ParseCertificate(block.Bytes)
        if err != nil {
            lastErr = err
            continue
        }
        pubkey, ok := x509Cert.PublicKey.(*rsa.PublicKey)
        if !ok {
            lastErr = errors.New("ErrNotRSAPublicKey")
            continue
        }

        signBytesHash := crypto.SHA256
        h := signBytesHash.New()
        h.Write(data)
        hashed := h.Sum(nil)
        err = rsa.VerifyPKCS1v15(pubkey, signBytesHash, hashed, sig)
        if err != nil {
            lastErr = err
            continue
        }

        return nil
    }

    return lastErr
}
我还在github上发布了验证步骤

更新 谷歌提供了一些验证SignBytes的方法。其中有一个文件
app identity samples read only/python/app_identity_test.py
有一个名为
buildjwt
的方法,该方法创建一个由SignBytes签名的JWT,JWT alg是RS256,在中使用SHA-256定义为RSASSA-PKCS1-v1_5


注意:我使用的是(请参阅“google.golang.org/appengine”导入),而不是经典的Go应用程序引擎运行时,尽管对于SignBytes来说没有太大区别。

太好了!我将向您发送拉取请求,以便您可以指定哪个应用程序已签名。。你可以使用这些来获取应用程序的证书。。。(我不记得是怎么发现的,也找不到任何文档。不过它已经运行了几年)
func PublicCertificates(c Context) ([]Certificate, error) 
type Certificate struct {
    KeyName string
    Data    []byte // PEM-encoded X.509 certificate
}
package yourpackage

import (
    "crypto"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "errors"
    "google.golang.org/appengine"
    "net/http"
)

func signAndVerify(request *http.Request) error {
    c := appengine.NewContext(request)
    data := []byte("test data to sign")
    _, sig, err := appengine.SignBytes(c, data)
    if err != nil {
        return err
    }

    certs, err := appengine.PublicCertificates(c)
    if err != nil {
        return err
    }

    lastErr := errors.New("ErrNoPublicCertificates")

    for _, cert := range certs {
        block, _ := pem.Decode(cert.Data)
        if block == nil {
            lastErr = errors.New("ErrPemDecodeFailure")
            continue
        }
        x509Cert, err := x509.ParseCertificate(block.Bytes)
        if err != nil {
            lastErr = err
            continue
        }
        pubkey, ok := x509Cert.PublicKey.(*rsa.PublicKey)
        if !ok {
            lastErr = errors.New("ErrNotRSAPublicKey")
            continue
        }

        signBytesHash := crypto.SHA256
        h := signBytesHash.New()
        h.Write(data)
        hashed := h.Sum(nil)
        err = rsa.VerifyPKCS1v15(pubkey, signBytesHash, hashed, sig)
        if err != nil {
            lastErr = err
            continue
        }

        return nil
    }

    return lastErr
}