title: JSch giving invalid private key errors for key pair generated by Java
body: <p>I am generating a keypair using Java's <code>KeyPairGenerator</code> for use with JGit. However, JSch (the underlying SSH implementation for JGit) keeps giving me <em>"invalid privatekey"</em> errors when trying to use the generated private key. </p>
  
  <p>Here is the stack trace:</p>
  
  <pre class="lang-none prettyprint-override"><code>Caught: org.eclipse.jgit.api.errors.TransportException: ssh://git@bitbucket.hostname/~wlaw/bitbucket_upgrade_test_repo.git: invalid privatekey: [B@4650a407
  org.eclipse.jgit.api.errors.TransportException: ssh://git@bitbucket.hostname/~wlaw/bitbucket_upgrade_test_repo.git: invalid privatekey: [B@4650a407
      at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:254)
      at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:306)
      at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:200)
      at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:1)
      at java_util_concurrent_Callable$call.call(Unknown Source)
      at Test.run(Test.groovy:95)
  Caused by: org.eclipse.jgit.errors.TransportException: ssh://git@bitbucket.hostname/~wlaw/bitbucket_upgrade_test_repo.git: invalid privatekey: [B@4650a407
      at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:183)
      at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:140)
      at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.&lt;init&gt;(TransportGitSsh.java:280)
      at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:170)
      at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:137)
      at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:123)
      at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1271)
      at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:243)
      ... 5 more
  Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B@4650a407
      at com.jcraft.jsch.KeyPair.load(KeyPair.java:948)
      at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:46)
      at com.jcraft.jsch.JSch.addIdentity(JSch.java:442)
      at Test$1.createDefaultJSch(Test.groovy:82)
      at org.eclipse.jgit.transport.JschConfigSessionFactory.getJSch(JschConfigSessionFactory.java:335)
      at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:293)
      at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:200)
      at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:130)
      ... 12 more
  </code></pre>
  
  <p>Here is my code:</p>
  
  <pre><code>KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA")
  keyGen.initialize(4096)
  KeyPair pair = keyGen.generateKeyPair()
  
  def pub = pair.public as RSAPublicKey
  def priv = pair.private as RSAPrivateCrtKey
  
  Base64.Encoder encoder = Base64.getEncoder();
  def publicKeyText = "ssh-rsa " + encoder.encodeToString(keyBlob(pub.publicExponent, pub.modulus))
  
  def id = bitbucket.post {
      request.uri.path = "/rest/ssh/1.0/keys"
      request.uri.query = [user: bitbucketUsername]
      request.body = new JsonBuilder([text: publicKeyText]).toPrettyString()
      response.success { FromServer fs, Object responseBody -&gt;
          responseBody.id
      }
      response.failure { FromServer fs, Object responseBody -&gt;
          println fs.statusCode
          println fs.message
          println fs.headers
          println responseBody
          null
      }
  }
  
  def privateKeyText = "-----BEGIN RSA PRIVATE KEY-----\n" +
      encoder.encodeToString(priv.getEncoded()) +
      "\n-----END RSA PRIVATE KEY-----\n"
  
  new File("priv").text = privateKeyText
  new File("pub").text = publicKeyText
  
  SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
      @Override
      protected void configure(OpenSshConfig.Host hc, com.jcraft.jsch.Session session) {}
  
      @Override
      protected JSch createDefaultJSch(FS fs) throws JSchException {
          JSch defaultJSch = super.createDefaultJSch(fs)
          defaultJSch.addIdentity("test", privateKeyText.bytes, publicKeyText.bytes, null)
      }
  };
  
  CloneCommand cloneCommand = Git.cloneRepository()
  cloneCommand.setURI("ssh://git@$bitbucketHostPort/$project/${repo}.git")
  cloneCommand.setTransportConfigCallback(new TransportConfigCallback() {
      @Override
      void configure(Transport transport) {
          SshTransport sshTransport = (SshTransport) transport
          sshTransport.setSshSessionFactory(sshSessionFactory)
      }
  })
  cloneCommand.call()
  </code></pre>
  
  <p>I did some debugging in the JSch source code, and found that the library is getting an ArrayIndexOutOfBoundsException on line 228 in com.jcraft.jsch.KeyPairRSA.java. </p>
  
  <p>Is it something I am doing wrong with formatting the keys for JSch? Or could this be a bug in Java's implementation of a KeyPair or perhaps JSch's implementation of parsing them?</p>
  
  <p>Here is an example keypair that is generated by my code:</p>
  
  <pre class="lang-none prettyprint-override"><code>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNPvFmy81wj3L4ndJzMcYFa9YctDzz0KvXyb9vg+UQ5622kyE255fwL4eatihL8/TrH1OOLQtSVjThLwWObx4fQ6bk25rJA0jS7G7CAfAQwbTY9JpNrcH5HHtiAhbUjEF/MXU6IlPNCmBMQPFh1eSa21aIdYie+KVgXQnUP4qN6ks1iR8XX4YHpg2KKhEoJtaVYGHp15EmpRvDYzsheqrcfyg4N5taGgG9/GzdfpeBWqCyJhrjgso85ARecGTpqCHqFNy46tXtIMR6FL36UDc/EpWifmf7oY4HVLa0DJpLq2BHmjRlUtiFFox1Jzk+shFiDZYwnCmdKnpCnlxFQ1Hv06XLgvcUx/0mkleh14Nme/b61pmJDO05v9zKho+9Q+lNgrTK+kOeC7I9PgUePyzWJteys/0MqENJxvM4g65/r9vzpcSvdEziSJ8Y3xI3qlzOa3Av1Jv5qIntgjEeAnth+AANdUP/GcpYbnCNp1QsjaZoFKFe2DcUTYM3CGzh0SFm9CeRfBV1phQ2+5gi1bH5ZiAfTNpksZz+SYIPyEsbaqNRcBk53htWfINShNVP7a/b/H7tyZs+zvMoHN2bZzsIMIUWO8Df+owpCK7ZT/EadDZzkzG2LUUUjm6aVsz2rjLFcvQtYOs0U/+suWhXNQ2dAW4psGLHkNb3NDHSzjzk7w==
  </code></pre>
  
  <pre class="lang-none prettyprint-override"><code>-----BEGIN RSA PRIVATE KEY-----
  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
  -----END RSA PRIVATE KEY-----
  </code></pre>