Google App Engine的Go运行时具有SignBytes函数,PublicCertificates函数和Certificate结构。
func SignBytes
func SignBytes(c Context, bytes []byte) (keyName string, signature []byte, err error)
SignBytes使用您的应用程序独有的私钥来标记字节。
func PublicCertificates
func PublicCertificates(c Context) ([]Certificate, error)
PublicCertificates检索应用程序的公共证书。他们 可用于验证SignBytes返回的签名。
输入证书
type Certificate struct { KeyName string Data []byte // PEM-encoded X.509 certificate }
证书代表该应用的公共证书。
很明显,应用程序应该遍历公共证书以验证签名。但目前尚不清楚如何生成或验证签名。 Go rsa package有两个功能来验证签名,VerifyPKCS1v15和VerifyPSS,每个函数都使用crypto.Hash标识符作为参数。目前,有15种不同的散列标识符(例如,crypto.MD5,crypto.SHA256),提供2x15 = 30种验证功能和散列标识符组合。
SignBytes如何验证签名?
答案 0 :(得分:4)
我通过尝试验证方案和散列类型的所有组合来发现这一点;我没有找到文件保证这是将使用的签名方案。
但是对于无畏者,下面是一个代码示例,用于签署数据并验证签名。
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上的package发布了验证步骤。
Google提供了一些验证SignBytes的sample code。在其中,有一个文件app-identity-samples-read-only/python/app_identity_test.py
有一个名为buildjwt
的方法,它创建一个由SignBytes签名的JWT,而JWT alg是RS256,在RFC 7518中定义为RSASSA-PKCS1 -v1_5使用SHA-256。
注意:我正在使用Go App Engine for Managed VMs(请参阅“google.golang.org/appengine”导入)而不是经典的Go App Engine运行时,尽管目的并没有太大差异SignBytes。