title: How to use an encrypted private key with golang ssh
body: <p>I would appreciate pointers because I cannot work out how to decrypt an encrypted key in order to use it with golang ssh. I'm attempting to mash together two other sources of code (including <a href="http://kukuruku.co/hub/golang/ssh-commands-execution-on-hundreds-of-servers-via-go" rel="noreferrer">this</a> one) but unable to get this to work.</p>
  
  <p>I think I'm getting to a DER but need to marshall this back to PEM in order to use it with crypto/ssh</p>
  
  <pre><code>-----BEGIN RSA PRIVATE KEY-----
  Proc-Type: 4,ENCRYPTED
  DEK-Info: AES-128-CBC,D7C72273BE168626E5B2D1BC72E56326
  ...
  -----END RSA PRIVATE KEY-----
  </code></pre>
  
  <p>I read it:</p>
  
  <pre><code>key, err := ioutil.ReadFile(privateKey)
  if err != nil {
      log.Fatalf("Unable to read private key: %v", err)
  }
  </code></pre>
  
  <p>With an unencrypted (!) key, I can then:</p>
  
  <pre><code>signer, err := ssh.ParsePrivateKey(key)
  if err != nil {
      log.Fatalf("Unable to parse private key: %v", err)
  }
  
  config := &amp;ssh.ClientConfig{
      User: username,
      Auth: []ssh.AuthMethod{
          ssh.PublicKeys(signer),
      },
  }
  </code></pre>
  
  <p>And this would work.</p>
  
  <p>I reused some code that I think gets me the decrypted PEM as a DER:</p>
  
  <pre><code>func decrypt(key []byte, password []byte) []byte {
      block, rest := pem.Decode(key)
      if len(rest) &gt; 0 {
          log.Fatalf("Extra data included in key")
      }
      der, err := x509.DecryptPEMBlock(block, password)
      if err != nil {
          log.Fatalf("Decrypt failed: %v", err)
      }
      return der
  }
  </code></pre>
  
  <p>But, how do I get from the DER to a signer?</p>
  
  <p>Or, what's the best way to solve this?</p>