Google app engine 如何验证appengine.SignBytes返回的签名?
Google App Engine的Go运行时有一个函数、一个函数和一个结构 func符号字节 SignBytes使用应用程序特有的私钥对字节进行签名 func公共证书 PublicCertificates检索应用程序的公共证书。他们 可用于验证SignBytes返回的签名 类型证书 证书表示应用程序的公共证书 很明显,应用程序需要遍历公共证书来验证签名。但目前尚不清楚签名是如何生成或验证的。Go’s有两个函数来验证签名,和,并且每个函数都使用一个标识符作为参数。目前,有15个不同的散列标识符(例如,crypto.MD5、crypto.SHA256),给出2x15=30个验证函数和散列标识符的组合 如何验证SignBytes生成的签名?使用SHA256验证PKCS1V15 我通过尝试验证方案和散列类型的所有组合发现了这一点;我没有找到文件保证这是将要使用的签名方案 但对于勇敢者来说,下面是一个对数据签名并验证签名的代码示例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个不同的散列标识符(
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
}