Skip to content

Instantly share code, notes, and snippets.

@sriramsa
Created December 17, 2016 04:16
Show Gist options
  • Save sriramsa/68d150ad50db4828f139e60a0efbde5a to your computer and use it in GitHub Desktop.
Save sriramsa/68d150ad50db4828f139e60a0efbde5a to your computer and use it in GitHub Desktop.
Golang: Convert Public key PEM bytes to Open SSH format
const (
samplePEMKeyA = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApIBaVZ8A6HraVxIVGEU+
psJx8S4nFQQykrJ751aicMUNFYThT/tl5Gvvl4H9eimB06iNf4zqnrvKwgtCYjFp
a5rJoaSxA675FBzYpzsHeygnPkt98mFGLRS6SJdNhvuE5QT6ostiLBufdpIyvSUP
cKdwL7ti8QyX3v8Lm7JrJ+DiGW8y3XYWm5kzlHdbah3DB2z2xh9+sQ1orXcxFTf7
CzVmfoTTO+QkeeTz/HG0gRu+EH1cxkMKP/BS8qOrFBFGWt3B/Vv0/lG4AILag+Dn
x4FfMxhlPtIXW4eUc5/SGaNHarJVN4y6mz4I3NvL3abMAWqpX1U9p/iO5kMLlFQX
qQIDAQAB
-----END PUBLIC KEY-----`
expectedSSHKeyA = `AAAAB3NzaC1yc2EAAAADAQABAAABAQCkgFpVnwDoetpXEhUYRT6mwnHxLicVBDKSsnvnVqJwxQ0VhOFP+2Xka++Xgf16KYHTqI1/jOqeu8rCC0JiMWlrmsmhpLEDrvkUHNinOwd7KCc+S33yYUYtFLpIl02G+4TlBPqiy2IsG592kjK9JQ9wp3Avu2LxDJfe/wubsmsn4OIZbzLddhabmTOUd1tqHcMHbPbGH36xDWitdzEVN/sLNWZ+hNM75CR55PP8cbSBG74QfVzGQwo/8FLyo6sUEUZa3cH9W/T+UbgAgtqD4OfHgV8zGGU+0hdbh5Rzn9IZo0dqslU3jLqbPgjc28vdpswBaqlfVT2n+I7mQwuUVBep`
)
// Converts PEM public key to OpenSSH format to be used in authorized_keys file
// Similar to: "ssh-keygen", "-i", "-m", "pkcs8", "-f", auth_keys_new_path
func PublicPEMtoOpenSSH(pemBytes []byte) (*string, error) {
// Decode and get the first block in the PEM file.
// In our case it should be the Public key block.
pemBlock, rest := pem.Decode(pemBytes)
if pemBlock == nil {
return nil, errors.New("invalid PEM public key passed, pem.Decode() did not find a public key")
}
if len(rest) > 0 {
return nil, errors.New("PEM block contains more than just public key")
}
// Confirm we got the PUBLIC KEY block type
if pemBlock.Type != "PUBLIC KEY" {
return nil, errors.Errorf("ssh: unsupported key type %q", pemBlock.Type)
}
// Convert to rsa
rsaPubKey, err := x509.ParsePKIXPublicKey(pemBlock.Bytes)
if err != nil {
return nil, errors.Wrap(err, "x509.parse pki public key")
}
// Confirm we got an rsa public key. Returned value is an interface{}
sshKey, ok := rsaPubKey.(*rsa.PublicKey)
if !ok {
return nil, errors.Wrap(err, "invalid PEM passed in from user")
}
// Generate the ssh public key
pub, err := ssh.NewPublicKey(sshKey)
if err != nil {
return nil, errors.Wrap(err, "new ssh public key from pem converted to rsa")
}
// Encode to store to file
sshPubKey := base64.StdEncoding.EncodeToString(pub.Marshal())
return &sshPubKey, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment