-
-
Save jokershigh/c7591bc2cee3b5d1dd9ec943ac365104 to your computer and use it in GitHub Desktop.
Sign string with go and openssl
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 main | |
/** | |
With openssl command: | |
# echo -n "string to sign" | openssl rsautl -inkey private.key -sign|base64 | |
or with openssl + sha256 (if it is used SignSHA256 function) | |
# openssl dgst -sha256 -sign private.key -out sign.txt.sha256 <(echo -n "string to sign") ; cat sign.txt.sha256 | base64 | |
With sign.go | |
# go run sign.go -word="string to sign" | |
Both commands should produce the same results. | |
*/ | |
import ( | |
"fmt" | |
"errors" | |
"flag" | |
"io/ioutil" | |
"crypto" | |
"crypto/sha256" | |
"crypto/x509" | |
"crypto/rand" | |
"crypto/rsa" | |
"encoding/base64" | |
"encoding/pem" | |
"encoding/base64" | |
) | |
// A Signer is can create signatures that verify against a public key. | |
type Signer interface { | |
// Sign returns raw signature for the given data. This method | |
// will apply the hash specified for the key type to the data. | |
Sign(data []byte) ([]byte, error) | |
SignSHA256(data []byte) ([]byte, error) | |
} | |
type rsaPrivateKey struct { | |
*rsa.PrivateKey | |
} | |
const ( | |
PRIVATE_KEY = "keys/private.key" | |
) | |
func loadPrivateKey(path string) (Signer, error) { | |
data, err := ioutil.ReadFile(path) | |
if err != nil { | |
return nil, err | |
} | |
return ParsePrivateKey(data) | |
} | |
// parsePublicKey parses a PEM encoded private key. | |
func ParsePrivateKey(pemBytes []byte) (Signer, error) { | |
block, _ := pem.Decode(pemBytes) | |
if block == nil { | |
return nil, errors.New("crypto: no key found") | |
} | |
var rawkey interface{} | |
switch block.Type { | |
case "RSA PRIVATE KEY": | |
rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes) | |
if err != nil { | |
return nil, err | |
} | |
rawkey = rsa | |
default: | |
return nil, fmt.Errorf("crypto: unsupported private key type %q", block.Type) | |
} | |
return newSignerFromKey(rawkey) | |
} | |
func newSignerFromKey(k interface{}) (Signer, error) { | |
var sshKey Signer | |
switch t := k.(type) { | |
case *rsa.PrivateKey: | |
sshKey = &rsaPrivateKey{t} | |
default: | |
return nil, fmt.Errorf("crypto: unsupported key type %T", k) | |
} | |
return sshKey, nil | |
} | |
// Signs directly the data | |
func (r *rsaPrivateKey) Sign(data []byte) ([]byte, error) { | |
return rsa.SignPKCS1v15(nil, r.PrivateKey, 0, data) | |
} | |
// Sign signs data with rsa-sha256 | |
func (r *rsaPrivateKey) SignSHA256(data []byte) ([]byte, error) { | |
h := sha256.New() | |
h.Write(data) | |
d := h.Sum(nil) | |
return rsa.SignPKCS1v15(rand.Reader, r.PrivateKey, crypto.SHA256, d) | |
} | |
func main() { | |
word := flag.String("word", "foo", "a string to encrypt") | |
flag.Parse() | |
toSign := *word | |
fmt.Println("word:", toSign) | |
signer, err := loadPrivateKey(PRIVATE_KEY); | |
if err != nil { | |
fmt.Printf("The signer could not be build: %v", err) | |
} | |
signed, err := signer.Sign([]byte(toSign)) | |
//signed, err := signer.SignSHA256([]byte(toSign)) | |
if err != nil { | |
fmt.Printf("Could not sign the request: %v", err) | |
} | |
sig := base64.StdEncoding.EncodeToString(signed) | |
fmt.Println(sig) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment