当前位置: 首页 > 面试题库 >

如何从Java生成与ssh兼容的id_rsa(.pub)

吕征
2023-03-14
问题内容

我正在寻找一种以编程方式在Java中创建与ssh兼容的id_rsa和id_rsa.pub文件的方法

我可以创建KeyPair:

KeyPairGenerator generator;
generator = KeyPairGenerator.getInstance("RSA");
// or: generator = KeyPairGenerator.getInstance("DSA");
generator.initialize(2048);
keyPair = generator.genKeyPair();

但是我不知道如何在KeyPair中创建PrivateKey和PublicKey的String表示形式。


问题答案:

ssh使用的密钥格式在RFC#4253中定义。RSA公钥的格式如下:

  string    "ssh-rsa"
  mpint     e /* key public exponent */
  mpint     n /* key modulus */

所有数据类型编码均在RFC#4251的#5部分中定义。字符串和mpint(多精度整数)类型的编码方式如下:

  4-bytes word: data length (unsigned big-endian 32 bits integer)
  n bytes     : binary representation of the data

例如,字符串“ ssh-rsa”的编码为:

  byte[] data = new byte[] {0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'};

编码公众:

   public byte[] encodePublicKey(RSAPublicKey key) throws IOException
   {
       ByteArrayOutputStream out = new ByteArrayOutputStream();
       /* encode the "ssh-rsa" string */
       byte[] sshrsa = new byte[] {0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'};
       out.write(sshrsa);
       /* Encode the public exponent */
       BigInteger e = key.getPublicExponent();
       byte[] data = e.toByteArray();
       encodeUInt32(data.length, out);
       out.write(data);
       /* Encode the modulus */
       BigInteger m = key.getModulus();
       data = m.toByteArray();
       encodeUInt32(data.length, out);
       out.write(data);
       return out.toByteArray();
   }

   public void encodeUInt32(int value, OutputStream out) throws IOException
   {
       byte[] tmp = new byte[4];
       tmp[0] = (byte)((value >>> 24) & 0xff);
       tmp[1] = (byte)((value >>> 16) & 0xff);
       tmp[2] = (byte)((value >>> 8) & 0xff);
       tmp[3] = (byte)(value & 0xff);
       out.write(tmp);
   }

要获得密钥的字符串表示形式,只需在Base64中编码返回的字节数组即可。

对于私钥编码,有两种情况:

  1. 私钥不受密码保护。在那种情况下,私钥根据PKCS#8标准进行编码,然后使用Base64进行编码。它可以通过打电话来获得私钥的PKCS8编码getEncodedRSAPrivateKey
  2. 私钥受密码保护。在这种情况下,密钥编码是OpenSSH专用格式。我不知道是否有任何格式的文档(当然,OpenSSH源代码除外)


 类似资料:
  • 我从一个openapi规范(3.0.1)设计开始,用openapi生成器maven-plugin(5.1.0)生成代码,然后我使用springdoc-openapi-ui进行Spring引导(2.5.4)。 我需要手动将生成的代码中的大部分注释从io.swagger.annotations.*迁移到io.swagger.v3.oas.annotations.*https://springdoc.o

  • 问题内容: 我只是使用qunit-reporter-junit生成以下XML: 但是当我运行它和xsd时,我在以下位置找到了它:https : //svn.jenkins-ci.org/trunk/hudson/dtkit/dtkit-format/dtkit-junit- model/src/main/resources/com/thalesgroup /dtkit/junit/model/xs

  • 我正在使用生成cacerts。 然后我使用,但我会遇到这样的例外: 这是兼容性问题吗?使用一个版本的java生成的Cacert是否与另一个版本的java不兼容?

  • 运行以下代码段(在Eclipse中设置了JDK7): 以下异常的结果: java.lang.UnsupportedClassVersionError:org/testfx/framework/junit/applicationtest:不支持major.minor版本52.0在java.lang.ClassLoader.DefineClass1(本机方法)在java.lang.ClassLoade

  • 有人使用Java9启动Payara 5吗? > < li> Payara版本:5.184 JDK版本:9.0.4 java 9.0.4 java(TM)SE运行时环境(版本9.0.4 11)java热点(TM)64位服务器虚拟机(版本9.0.4.11,混合模式) 操作系统:Windows 10,版本1709(操作系统版本:16299.309) 发出命令时: asadmin start-domain

  • 我需要使用AES算法加密Java应用程序中的一些值,并在我的应用程序的Javascript模块中解密相同的值。 我在互联网上看到了一些例子,但在兼容性方面似乎有些不同。 多谢了。