Сбой декодирования ECDSA: Исключение в потоке "main" java.security.SignatureException: ошибка при декодировании байтов подписи
Я пытаюсь проверить подпись ECDSA, используя Java, ключ был создан с помощью golang:
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"reflect"
)
func doit(){
privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
publicKey := &privateKey.PublicKey
if !elliptic.P384().IsOnCurve(publicKey.X, publicKey.Y) {
fmt.Printf(" public key invalid. ")
}
encPriv, encPub := encode(privateKey, publicKey)
fmt.Println(encPriv)
fmt.Println(encPub)
}
подпись происходит здесь: (сообщение было закодировано golang, используя этот метод):
func SignMessage(message []byte) (r *big.Int, s *big.Int, err error) {
zero := big.NewInt(0)
// Hash message:
h := sha1.New()
io.WriteString(h, string(message))
hashBytes := h.Sum(nil)
hash := fmt.Sprintf("%x", hashBytes)
// hash message
// get private key from disk:
pemEncoded, err := ioutil.ReadFile("./ecc/eccpriv.pem")
if err != nil {
return zero, zero, err
}
pemEncodedPub, err := ioutil.ReadFile("./ecc/eccpub.pem")
if err != nil {
return zero, zero, err
}
var priv *ecdsa.PrivateKey
//var _pub *ecdsa.PublicKey
priv, _, err = ECCDecodeFromPem(pemEncoded, pemEncodedPub)
if err != nil {
return zero, zero, err
}
r, s, err = ecdsa.Sign(rand.Reader, priv, []byte(hash))
if err != nil {
return zero, zero, err
}
return r, s, nil
}
аспект декодирования происходит здесь:
//Verify Response
String signature = ac.getECCDSAPublicKeyFromServer();
String cleanSignature = ac.cleanBytes(signature);
byte[] bSignature = Base64.getDecoder().decode(cleanSignature);
System.out.println(cleanSignature);
PublicKey ecdsaPublicKey = ac.getPemPublicKeyFromString(signature,"ECDSA");
//PublicKey ecdsaPublicKey = ac.getECDSAKeyFromBytes(cleanSignature.getBytes("UTF-8"));
Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
ecdsaVerify.initVerify(ecdsaPublicKey);
ecdsaVerify.update(json_response.getBytes("UTF-8"));
System.out.println("SIG:");
for(int i=0;i<bSignature.length;i++){
System.out.println(bSignature[i]);
}
System.out.println(new String(bSignature, StandardCharsets.UTF_8));
System.out.println("/SIG");
boolean result = ecdsaVerify.verify(bSignature);
System.out.println("Result is:"+result);
Однако, к сожалению, программа не работает, потому что:
Exception in thread "main" java.security.SignatureException: error decoding signature bytes.
at org.bouncycastle.jcajce.provider.asymmetric.util.DSABase.engineVerify(Unknown Source)
at java.base/java.security.Signature$Delegate.engineVerify(Signature.java:1245)
at java.base/java.security.Signature.verify(Signature.java:674)
at ...
Это вызывает интересную дилемму, поскольку открытый ключ:
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEBiTlkxxYVLduJeiQ7V1AqG4bY9lxrxLX
un+qd4BeaICC1Yx/nsDvvXEPwfCYwXgnyk3u7DV3ldUiaXCIr89OoNei6D2Xgrs3
KYtpVEv7ylnUzo8xZH3/mMdLMUiy6fl8
-----END PUBLIC KEY-----
Кажется, правильно, согласно этому сайту:
Ключ был сгенерирован правильно, и ASN.1 Parse правильно его декодирует. Почему java не нравится мой код?
Кроме того, прошу прощения за мой плохой отступ.
1 ответ
Я думаю, что ваша проблема здесь:
hash := fmt.Sprintf("%x", hashBytes)
И вы должны передать hashBytes непосредственно
r, s, err = ecdsa.Sign(rand.Reader, priv, hashBytes)