【问题标题】:Verify rsa.SignPKCS1v15 signature generated in golang in Java在 Java 中验证 golang 中生成的 rsa.SignPKCS1v15 签名
【发布时间】:2015-04-02 21:25:18
【问题描述】:

我试图让 Java 验证签名的 SHA-1 哈希,但它一直返回错误。我在 Go 中有以下代码,它生成一个 RSA 密钥对并签名并返回任何命中 /sign 端点的消息以及十六进制编码的哈希和公钥模数和指数:

package main

import (
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "strconv"
)

var PrivKey *rsa.PrivateKey

type Message struct {
    Message string `json:"message"`
}

func (msg *Message) Decode(r io.Reader) error {
    return json.NewDecoder(r).Decode(&msg)
}

type Signature struct {
    Hash      string `json:"hash"`
    Signature string `json:"signature"`
    N         string `json:"N"`
    E         string `json:"E"`
}

func hash(msg string) []byte {
    sh := crypto.SHA1.New()
    sh.Write([]byte(msg))
    hash := sh.Sum(nil)
    return hash
}

func SignWithKey(msg Message) Signature {
    hash := hash(msg.Message)
    bytes, err := rsa.SignPKCS1v15(rand.Reader, PrivKey, crypto.SHA1, hash)
    if err != nil {
        panic(err)
    }
    signature := hex.EncodeToString(bytes)
    sig := Signature{
        hex.EncodeToString(hash),
        signature,
        PrivKey.PublicKey.N.String(),
        strconv.Itoa(PrivKey.PublicKey.E),
    }
    return sig
}

func sign(w http.ResponseWriter, r *http.Request) {
    fmt.Println("/sign")
    var msg Message
    err := msg.Decode(r.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println("Signing: " + msg.Message)
    signature := SignWithKey(msg)
    js, err := json.Marshal(signature)
    fmt.Println(string(js))

    w.Header().Set("Content-Type", "application/json")
    w.Write(js)
}

func LoadKeys() {
    // generate private key
    var err error
    PrivKey, err = rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        fmt.Println(err)
    }
}

func main() {

    fmt.Println("Loading Keys")
    LoadKeys()
    fmt.Println("Keys Loaded")
    http.HandleFunc("/sign", sign)

    http.ListenAndServe(":8080", nil)
}

在 Java/Android 端,我有这段代码,它在发送相关位后使用未解析的 JSON 对象命中此函数,但一旦到达签名验证部分,它总是返回 false:

protected void onPostExecute(String result) {
            if (result == null) {
                tv.setText("NULL");
                return;
            }
            JsonElement jelement = new JsonParser().parse(result);
            JsonObject jobject = jelement.getAsJsonObject();
            String signature = jobject.getAsJsonPrimitive("signature").getAsString();
            BigInteger N = jobject.getAsJsonPrimitive("N").getAsBigInteger();
            BigInteger E = jobject.getAsJsonPrimitive("E").getAsBigInteger();
            String hash = jobject.getAsJsonPrimitive("hash").getAsString();
            java.security.spec.RSAPublicKeySpec spec = new java.security.spec.RSAPublicKeySpec(N, E);

            try {
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PublicKey pk = keyFactory.generatePublic(spec);

                MessageDigest digest = MessageDigest.getInstance("SHA1");
                byte[] inputBytes = msg.getBytes("UTF8");
                byte[] hashedBytes = digest.digest(inputBytes);

                Signature sig = Signature.getInstance("SHA1withRSA", "SC");
                sig.initVerify( pk );
                sig.update( hashedBytes );
                boolean ret = sig.verify( Hex.decode(signature) );
                if (ret) {
                    tv.setText(output + "Verified");
                } else {
                    tv.setText(output + "NOT VERIFIED");
                }
            }
            catch (Exception e) {
                Log.i("error", e.toString());
            }  
        }
    }

【问题讨论】:

    标签: java android go rsa bouncycastle


    【解决方案1】:

    在 Java 中,您不需要在签名或验证之前对消息进行哈希处理。这意味着发送到 sig.update 的字节不应该是 hashedBytes,而是 inputBytes。

    【讨论】:

      【解决方案2】:

      如果您不想在 Go 中对内容进行哈希处理而只对原始数据进行签名,则可以使用以下代码:

      signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.Hash(0), []byte(message))
      

      【讨论】:

        猜你喜欢
        • 2019-12-27
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        • 2020-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多