package service import ( "crypto/dsa" "crypto/rand" "crypto/sha256" "encoding/asn1" "encoding/base64" "encoding/pem" "errors" "log" "math/big" "os" ) func encodeSHA256WithDSA() (string, error) { //read pem file from file system privateKeyData, err := os.ReadFile("./file.pem") if err != nil { log.Fatal(err) } hash, err := hash("dataToEncode") if err != nil { log.Fatal("hash:", err) } out, err := sign(hash, privateKeyData) return base64.StdEncoding.EncodeToString(out), nil } func hash(file []byte) ([]byte, error) { sum := sha256.Sum256(file) return sum[:], nil } func sign(hash []byte, file []byte) ([]byte, error) { block, _ := pem.Decode(file) if block == nil { return nil, errors.New("Failed to parse private key PEM") } priv, error := ParseDSAPrivateKey(block.Bytes) if error != nil { return nil, error } var s dsaSignature s.R, s.S, error = dsa.Sign(rand.Reader, priv, hash) if error != nil { return nil, error } return asn1.Marshal(s) } func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) { var k struct { Version int P *big.Int Q *big.Int G *big.Int Pub *big.Int Priv *big.Int } rest, err := asn1.Unmarshal(der, &k) if err != nil { return nil, errors.New("failed to parse DSA key: " + err.Error()) } if len(rest) > 0 { return nil, errors.New("garbage after DSA key") } return &dsa.PrivateKey{ PublicKey: dsa.PublicKey{ Parameters: dsa.Parameters{ P: k.P, Q: k.Q, G: k.G, }, Y: k.Pub, }, X: k.Priv, }, nil } type dsaPrivateKey struct { Version int P, Q, G, Y, X *big.Int } type dsaSignature struct { R, S *big.Int }