Forked from devinodaniel/gist:8f9b8a4f31573f428f29ec0e884e6673
Last active
August 17, 2020 23:46
-
-
Save azakordonets/536b4ec1a34f8bf4b685501dbd44a8f9 to your computer and use it in GitHub Desktop.
Generate SSH RSA Private/Public Key pair with Golang
This file contains 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
// This shows an example of how to generate a SSH RSA Private/Public key pair and save it locally | |
package main | |
import ( | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/x509" | |
"encoding/pem" | |
"golang.org/x/crypto/ssh" | |
"io/ioutil" | |
"log" | |
) | |
func main() { | |
savePrivateFileTo := "./id_rsa_test" | |
savePublicFileTo := "./id_rsa_test.pub" | |
bitSize := 4096 | |
privateKey, err := generatePrivateKey(bitSize) | |
if err != nil { | |
log.Fatal(err.Error()) | |
} | |
publicKeyBytes, err := generatePublicKey(&privateKey.PublicKey) | |
if err != nil { | |
log.Fatal(err.Error()) | |
} | |
privateKeyBytes := encodePrivateKeyToPEM(privateKey) | |
err = writeKeyToFile(privateKeyBytes, savePrivateFileTo) | |
if err != nil { | |
log.Fatal(err.Error()) | |
} | |
err = writeKeyToFile([]byte(publicKeyBytes), savePublicFileTo) | |
if err != nil { | |
log.Fatal(err.Error()) | |
} | |
} | |
// generatePrivateKey creates a RSA Private Key of specified byte size | |
func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) { | |
// Private Key generation | |
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize) | |
if err != nil { | |
return nil, err | |
} | |
// Validate Private Key | |
err = privateKey.Validate() | |
if err != nil { | |
return nil, err | |
} | |
log.Println("Private Key generated") | |
return privateKey, nil | |
} | |
// encodePrivateKeyToPEM encodes Private Key from RSA to PEM format | |
func encodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte { | |
// Get ASN.1 DER format | |
privDER := x509.MarshalPKCS1PrivateKey(privateKey) | |
// pem.Block | |
privBlock := pem.Block{ | |
Type: "RSA PRIVATE KEY", | |
Headers: nil, | |
Bytes: privDER, | |
} | |
// Private key in PEM format | |
privatePEM := pem.EncodeToMemory(&privBlock) | |
return privatePEM | |
} | |
// generatePublicKey take a rsa.PublicKey and return bytes suitable for writing to .pub file | |
// returns in the format "ssh-rsa ..." | |
func generatePublicKey(privatekey *rsa.PublicKey) ([]byte, error) { | |
publicRsaKey, err := ssh.NewPublicKey(privatekey) | |
if err != nil { | |
return nil, err | |
} | |
pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey) | |
log.Println("Public key generated") | |
return pubKeyBytes, nil | |
} | |
// writePemToFile writes keys to a file | |
func writeKeyToFile(keyBytes []byte, saveFileTo string) error { | |
err := ioutil.WriteFile(saveFileTo, keyBytes, 0600) | |
if err != nil { | |
return err | |
} | |
log.Printf("Key saved to: %s", saveFileTo) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment