Files
Netis---JWT-naloga/internal/crypto/keys.go
2026-03-12 20:09:16 +01:00

110 lines
2.7 KiB
Go

package appcrypto
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
)
// Ustvari nov ECDSA P-256 zasebni kljuc v PEM obliki.
func UstvariZasebniKljucECDSAP256PEM() ([]byte, error) {
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, err
}
der, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: der,
}
return pem.EncodeToMemory(block), nil
}
// Podpisi sporocilo z zasebnim kljucem iz PEM in vrni Base64URL podpis.
func PodpisiSporociloSPEM(pemPrivateKey []byte, message []byte) (string, error) {
privateKey, err := PreberiZasebniKljucPEM(pemPrivateKey)
if err != nil {
return "", err
}
hash := sha256.Sum256(message)
signature, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:])
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(signature), nil
}
// Preveri podpis sporocila z javnim delom zasebnega PEM kljuca.
func PreveriPodpisSPEM(pemPrivateKey []byte, message []byte, signatureBase64URL string) (bool, error) {
privateKey, err := PreberiZasebniKljucPEM(pemPrivateKey)
if err != nil {
return false, err
}
signature, err := base64.RawURLEncoding.DecodeString(signatureBase64URL)
if err != nil {
return false, err
}
hash := sha256.Sum256(message)
ok := ecdsa.VerifyASN1(&privateKey.PublicKey, hash[:], signature)
return ok, nil
}
// Preberi ECDSA zasebni kljuc iz PEM zapisa.
func PreberiZasebniKljucPEM(pemPrivateKey []byte) (*ecdsa.PrivateKey, error) {
block, _ := pem.Decode(pemPrivateKey)
if block == nil {
return nil, errors.New("invalid PEM block")
}
if block.Type != "EC PRIVATE KEY" {
return nil, errors.New("PEM is not EC PRIVATE KEY")
}
return x509.ParseECPrivateKey(block.Bytes)
}
// Preberi ECDSA javni kljuc iz PEM zapisa.
func PreberiJavniKljucPEM(pemPublicKey []byte) (*ecdsa.PublicKey, error) {
block, _ := pem.Decode(pemPublicKey)
if block == nil {
return nil, errors.New("invalid PEM block")
}
if block.Type != "PUBLIC KEY" {
return nil, errors.New("PEM is not PUBLIC KEY")
}
pubAny, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pub, ok := pubAny.(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("public key is not ECDSA")
}
return pub, nil
}
// Pretvori ECDSA javni kljuc v PEM zapis.
func PretvoriJavniKljucVPEM(publicKey *ecdsa.PublicKey) ([]byte, error) {
der, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: der,
}
return pem.EncodeToMemory(block), nil
}