Last active
          June 28, 2023 21:54 
        
      - 
      
- 
        Save valentinconan/6dc46dd64483669b8ee621b58ba19e42 to your computer and use it in GitHub Desktop. 
    Signature using SHA256 with DSA and a PEM file as private key
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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 | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment