doumao1887 2015-09-09 18:05
浏览 70
已采纳

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

Google App Engine's Go runtime has a SignBytes function, a PublicCertificates function, and a Certificate structure.

func SignBytes

func SignBytes(c Context, bytes []byte) (keyName string, signature []byte, err error) 

SignBytes signs bytes using a private key unique to your application.

func PublicCertificates

func PublicCertificates(c Context) ([]Certificate, error) 

PublicCertificates retrieves the public certificates for the app. They can be used to verify a signature returned by SignBytes.

type Certificate

type Certificate struct {
    KeyName string
    Data    []byte // PEM-encoded X.509 certificate
}

Certificate represents a public certificate for the app.

It's clear that the application is expected to iterate through the public certificates to verify the signature. But it is not clear how the signature is generate or verified. Go's rsa package has two functions to verify signatures, VerifyPKCS1v15 and VerifyPSS, and each of those functions takes a crypto.Hash identifier as a parameter. Currently, there are 15 different hash identifiers (e.g., crypto.MD5, crypto.SHA256) giving 2x15=30 combinations of verification function and hash identifier.

How is the signature produced by SignBytes verified?

  • 写回答

1条回答 默认 最新

  • dqwh1119 2015-09-10 01:52
    关注

    VerifyPKCS1v15 using SHA256

    I discovered this by trying all combinations of verification scheme and hash type; I did not find documentation guaranteeing this is the signature scheme that will be used.

    But for the intrepid, below is a code sample that signs data and verifies the signature.

    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
    }
    

    I've also published the the verify step in a package on github.

    Update

    Google provides some sample code that verifies SignBytes. In it, there is a file app-identity-samples-read-only/python/app_identity_test.py has a method named buildjwt that creates a JWT signed by SignBytes, and the JWT alg is RS256, which is defined in RFC 7518 to be RSASSA-PKCS1-v1_5 using SHA-256.

    Note: I'm using Go App Engine for Managed VMs (see "google.golang.org/appengine" import) rather than the classic Go App Engine runtime, though there isn't really much different for the purposes of SignBytes.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大