You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.3 KiB

  1. // This shows an example of how to generate a SSH RSA Private/Public key pair and save it locally
  2. package utils
  3. import (
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "encoding/pem"
  8. "io/ioutil"
  9. "log"
  10. "golang.org/x/crypto/ssh"
  11. )
  12. func GenerateSSHKeys(sshPrivKeyFile string, sshPubKeyFile string) {
  13. savePrivateFileTo := sshPrivKeyFile
  14. savePublicFileTo := sshPubKeyFile
  15. bitSize := 4096
  16. privateKey, err := generatePrivateKey(bitSize)
  17. if err != nil {
  18. log.Fatal(err.Error())
  19. }
  20. publicKeyBytes, err := generatePublicKey(&privateKey.PublicKey)
  21. if err != nil {
  22. log.Fatal(err.Error())
  23. }
  24. privateKeyBytes := encodePrivateKeyToPEM(privateKey)
  25. err = writeKeyToFile(privateKeyBytes, savePrivateFileTo)
  26. if err != nil {
  27. log.Fatal(err.Error())
  28. }
  29. err = writeKeyToFile([]byte(publicKeyBytes), savePublicFileTo)
  30. if err != nil {
  31. log.Fatal(err.Error())
  32. }
  33. }
  34. // generatePrivateKey creates a RSA Private Key of specified byte size
  35. func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
  36. // Private Key generation
  37. privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
  38. if err != nil {
  39. return nil, err
  40. }
  41. // Validate Private Key
  42. err = privateKey.Validate()
  43. if err != nil {
  44. return nil, err
  45. }
  46. log.Println("Private Key generated")
  47. return privateKey, nil
  48. }
  49. // encodePrivateKeyToPEM encodes Private Key from RSA to PEM format
  50. func encodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
  51. // Get ASN.1 DER format
  52. privDER := x509.MarshalPKCS1PrivateKey(privateKey)
  53. // pem.Block
  54. privBlock := pem.Block{
  55. Type: "RSA PRIVATE KEY",
  56. Headers: nil,
  57. Bytes: privDER,
  58. }
  59. // Private key in PEM format
  60. privatePEM := pem.EncodeToMemory(&privBlock)
  61. return privatePEM
  62. }
  63. // generatePublicKey take a rsa.PublicKey and return bytes suitable for writing to .pub file
  64. // returns in the format "ssh-rsa ..."
  65. func generatePublicKey(privatekey *rsa.PublicKey) ([]byte, error) {
  66. publicRsaKey, err := ssh.NewPublicKey(privatekey)
  67. if err != nil {
  68. return nil, err
  69. }
  70. pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey)
  71. log.Println("Public key generated")
  72. return pubKeyBytes, nil
  73. }
  74. // writePemToFile writes keys to a file
  75. func writeKeyToFile(keyBytes []byte, saveFileTo string) error {
  76. err := ioutil.WriteFile(saveFileTo, keyBytes, 0600)
  77. if err != nil {
  78. return err
  79. }
  80. log.Printf("Key saved to: %s", saveFileTo)
  81. return nil
  82. }