diff --git a/golang/README.md b/golang/README.md new file mode 100644 index 0000000..11e16c1 --- /dev/null +++ b/golang/README.md @@ -0,0 +1,7 @@ +# Learning Tools: Golang + +The contents of this folder are focused on improving knowledge in programming with Golang. + +## Contents + +**generate-ssh-key**: This folder provides some code for generating SSH keys in Golang. diff --git a/golang/generate-ssh-key/README.md b/golang/generate-ssh-key/README.md new file mode 100644 index 0000000..230855f --- /dev/null +++ b/golang/generate-ssh-key/README.md @@ -0,0 +1,5 @@ +# Generate an SSH Key in Golang + +The code in this directory was heavily derived from [this StackOverflow page](https://stackoverflow.com/questions/21151714/go-generate-an-ssh-public-key). + +This was written and tested with Golang 1.18 on an ARM64-based Mac, but it should run fine on any platform or architecture supported by Go. diff --git a/golang/generate-ssh-key/go.mod b/golang/generate-ssh-key/go.mod new file mode 100644 index 0000000..c1ff4da --- /dev/null +++ b/golang/generate-ssh-key/go.mod @@ -0,0 +1,7 @@ +module go-sshkey + +go 1.18 + +require golang.org/x/crypto v0.7.0 + +require golang.org/x/sys v0.6.0 // indirect diff --git a/golang/generate-ssh-key/main.go b/golang/generate-ssh-key/main.go new file mode 100644 index 0000000..4e166f4 --- /dev/null +++ b/golang/generate-ssh-key/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "log" + + "golang.org/x/crypto/ssh" +) + +func main() { + // Generate a 4096-bit RSA private key + privateKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + log.Printf("error encountered: %s", err.Error()) + } + privateKeyDer := x509.MarshalPKCS1PrivateKey(privateKey) + privateKeyBlock := pem.Block{ + Type: "RSA PRIVATE KEY", + Headers: nil, + Bytes: privateKeyDer, + } + privateKeyPem := string(pem.EncodeToMemory(&privateKeyBlock)) + fmt.Println(string(privateKeyPem)) + + // Generate a matching public key + publicKey := privateKey.PublicKey + publicKeyDer, err := x509.MarshalPKIXPublicKey(&publicKey) + if err != nil { + log.Printf("error encountered: %s", err.Error()) + } + publicKeyBlock := pem.Block{ + Type: "PUBLIC KEY", + Headers: nil, + Bytes: publicKeyDer, + } + publicKeyPem := string(pem.EncodeToMemory(&publicKeyBlock)) + fmt.Println(string(publicKeyPem)) + + // Generate the public key in OpenSSH authorized_keys format + sshPubKey, err := ssh.NewPublicKey(&publicKey) + if err != nil { + log.Printf("error encountered: %s", err.Error()) + } + fmt.Println(string(ssh.MarshalAuthorizedKey(sshPubKey))) +}