Forked from devinodaniel/gist:8f9b8a4f31573f428f29ec0e884e6673
Created
July 5, 2020 04:32
-
-
Save didip/5df46cdcf3f41b8d67cfce66afc1427c 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