110 lines
2.7 KiB
Go
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
|
|
}
|