验证Java Golang中生成的rsa.SignPKCS1v15签名

我试图让Java验证签名的SHA-1哈希,但是它一直返回false。我在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中,您无需在签名或验证消息之前对消息进行哈希处理。这意味着发送到sig.update的字节不应为hashBytes,而应为inputBytes。

以上是 验证Java Golang中生成的rsa.SignPKCS1v15签名 的全部内容, 来源链接: utcz.com/qa/431532.html

回到顶部