将openSSH rsa密钥转换为javax.crypto.Cipher兼容格式

马克·米科夫斯基

有没有办法以编程方式将Jsch生成的SSH RSA密钥转换为javax.crypto.Cipher可以用于加密的格式我主要看到类似的回答这个

openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key_file -nocrypt > pkcs8_key

但是我没有访问openSSL或shell命令的权限。顺便说一句:我只使用JDK6。

由于@erickson对他的帮助,我可以从转换RFC4716的公共密钥使用的指数和模量作为Java公共密钥BigInteger传递给类型KeyFactoryRSAPublicKeySpec他的解决方案如下。

现在,我正在尝试转换私钥。这是使用privateJsch.key生成的示例writePrivateKey(str filename)

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC0ouLgTjmKjHU6UjNSL8HyTIdFM1UdVpgU81paWKreN8L36YoT
goZQHeyyUCCHmq3r3cKaySyu93mHBY0l76qSAIRZgE1IAFkBhNWBdlJ9UYA9HXm/
MqTQHbpqz0EYGE9TsFHS8dn1/utsJxKSWZ4xPNYjfS4Ps6G84iRwfdrIbQIDAQAB
AoGAKv3xnY1AqLcRV5Yk3NS9Blwsfc3f3iG0BJh+0q3zzPvcjYCp+kbAjOTyZuYn
N98asd6P6KMk3WfNJtOtanAGWl46bmtzNsQtSr5rVQEgs2w8i2yJcwVAYf2Td4qX
m3dH+roJA/CEFRSDat4sUfjOVmsYQXIBa0W2XTpp+7T1U4ECQQD1wSR6iTz7Bja0
MPcizDbRTRQHALBf7E8j8YOLpN/IGSox9pT+ktjsI2vMaD+b3SM4s0FD8quBlppE
o5FAguHxAkEAvCrCK7eZU3H+Ul1iw9Kd3WPHjDvQcdT5rEL+NSYEZyHgU7ipXEih
UHvK47Bkte/PVIu3jBFBnMujA0XiT0gSPQJBAI3+8j/nChgU6AjHfhRaIJZgzeCZ
8k8KcFPZWWOXeUHZ4HqL+lz5pmMSuFecKJy7cn1xfZVwIs62oR5l0CiRN1ECQCui
CqaSi3ZjH6M/znA0PbEhuxsUn7BVv5OncUUnzKuRmnAviO5CVU3Rdum3dJMPydcE
Ewri0YEnY2SV5vWVc80CQH43uBbshz7ju3DdVykHFrRElQB+f0YMK3Ad7eu+us0w
dLrOOoXP0T60B/bMTo8rdMa6XU/0w/w8FsOqoxNY23U=
-----END RSA PRIVATE KEY-----

使用openssl asn1parse -in privateJsch.key -out privateJsch.deryeild:

$ openssl asn1parse -in privateJsch.key -out privateJsch.der
    0:d=0  hl=4 l= 604 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=3 l= 129 prim: INTEGER           :B4A2E2E04E398A8C753A5233522FC1F24C874533551D569814F35A5A58AADE37C2F7E98A138286501DECB25020879AADEBDDC29AC92CAEF77987058D25EFAA92008459804D4800590184D58176527D51803D1D79BF32A4D01DBA6ACF4118184F53B051D2F1D9F5FEEB6C271292599E313CD6237D2E0FB3A1BCE224707DDAC86D
  139:d=1  hl=2 l=   3 prim: INTEGER           :010001
  144:d=1  hl=3 l= 128 prim: INTEGER           :2AFDF19D8D40A8B711579624DCD4BD065C2C7DCDDFDE21B404987ED2ADF3CCFBDC8D80A9FA46C08CE4F266E62737DF1AB1DE8FE8A324DD67CD26D3AD6A70065A5E3A6E6B7336C42D4ABE6B550120B36C3C8B6C8973054061FD93778A979B7747FABA0903F0841514836ADE2C51F8CE566B184172016B45B65D3A69FBB4F55381
  275:d=1  hl=2 l=  65 prim: INTEGER           :F5C1247A893CFB0636B430F722CC36D14D140700B05FEC4F23F1838BA4DFC8192A31F694FE92D8EC236BCC683F9BDD2338B34143F2AB81969A44A3914082E1F1
  342:d=1  hl=2 l=  65 prim: INTEGER           :BC2AC22BB7995371FE525D62C3D29DDD63C78C3BD071D4F9AC42FE3526046721E053B8A95C48A1507BCAE3B064B5EFCF548BB78C11419CCBA30345E24F48123D
  409:d=1  hl=2 l=  65 prim: INTEGER           :8DFEF23FE70A1814E808C77E145A209660CDE099F24F0A7053D95963977941D9E07A8BFA5CF9A66312B8579C289CBB727D717D957022CEB6A11E65D028913751
  476:d=1  hl=2 l=  64 prim: INTEGER           :2BA20AA6928B76631FA33FCE70343DB121BB1B149FB055BF93A7714527CCAB919A702F88EE42554DD176E9B774930FC9D704130AE2D18127636495E6F59573CD
  542:d=1  hl=2 l=  64 prim: INTEGER           :7E37B816EC873EE3BB70DD57290716B44495007E7F460C2B701DEDEBBEBACD3074BACE3A85CFD13EB407F6CC4E8F2B74C6BA5D4FF4C3FC3C16C3AAA31358DB75

base64解码关键部分会产生十六进制的ASN.1 PKCS#1组件(请参阅RFC3447),以下针对此示例,其他将遵循具有不同字节数的模式

30:82:    x3082 == ASN.1 Sequence
02:5C:    Key Length == 604 bytes
02:01:    x02 == ASN.1 integer, Value Length == 1 byte
00:       Version == 0
02:81:81: x02 == ASN.1 integer, Modulus Length == 129 bytes
00:B4:A2:E2:E0:4E:39:8A:8C:75:3A:52:33:52:2F:C1:
F2:4C:87:45:33:55:1D:56:98:14:F3:5A:5A:58:AA:DE:
37:C2:F7:E9:8A:13:82:86:50:1D:EC:B2:50:20:87:9A:
AD:EB:DD:C2:9A:C9:2C:AE:F7:79:87:05:8D:25:EF:AA:
92:00:84:59:80:4D:48:00:59:01:84:D5:81:76:52:7D:
51:80:3D:1D:79:BF:32:A4:D0:1D:BA:6A:CF:41:18:18:
4F:53:B0:51:D2:F1:D9:F5:FE:EB:6C:27:12:92:59:9E:
31:3C:D6:23:7D:2E:0F:B3:A1:BC:E2:24:70:7D:DA:C8:
6D:       Modulus
02:03:    x02 == ASN.1 integer, Value Length == 3 bytes
01:00:01: Public Exponent
02:81:80: x02 == ASN.1 integer, Value Length == 128 bytes
2A:FD:F1:9D:8D:40:A8:B7:11:57:96:24:DC:D4:BD:06:
5C:2C:7D:CD:DF:DE:21:B4:04:98:7E:D2:AD:F3:CC:FB:
DC:8D:80:A9:FA:46:C0:8C:E4:F2:66:E6:27:37:DF:1A:
B1:DE:8F:E8:A3:24:DD:67:CD:26:D3:AD:6A:70:06:5A:
5E:3A:6E:6B:73:36:C4:2D:4A:BE:6B:55:01:20:B3:6C:
3C:8B:6C:89:73:05:40:61:FD:93:77:8A:97:9B:77:47:
FA:BA:09:03:F0:84:15:14:83:6A:DE:2C:51:F8:CE:56:
6B:18:41:72:01:6B:45:B6:5D:3A:69:FB:B4:F5:53:81:
          Private Exponent 
02:41:    x02 == ASN.1 integer, Value Length == 65 bytes
00:F5:C1:24:7A:89:3C:FB:06:36:B4:30:F7:22:CC:36:
D1:4D:14:07:00:B0:5F:EC:4F:23:F1:83:8B:A4:DF:C8:
19:2A:31:F6:94:FE:92:D8:EC:23:6B:CC:68:3F:9B:DD:
23:38:B3:41:43:F2:AB:81:96:9A:44:A3:91:40:82:E1:
F1:       Prime P
02:41:    x02 == ASN.1 integer, Value Length == 65 bytes
00:BC:2A:C2:2B:B7:99:53:71:FE:52:5D:62:C3:D2:9D:
DD:63:C7:8C:3B:D0:71:D4:F9:AC:42:FE:35:26:04:67:
21:E0:53:B8:A9:5C:48:A1:50:7B:CA:E3:B0:64:B5:EF:
CF:54:8B:B7:8C:11:41:9C:CB:A3:03:45:E2:4F:48:12:
3D:       Prime Q
02:41:    x02 == ASN.1 integer, Value Length == 65 bytes
00:8D:FE:F2:3F:E7:0A:18:14:E8:08:C7:7E:14:5A:20:
96:60:CD:E0:99:F2:4F:0A:70:53:D9:59:63:97:79:41:
D9:E0:7A:8B:FA:5C:F9:A6:63:12:B8:57:9C:28:9C:BB:
72:7D:71:7D:95:70:22:CE:B6:A1:1E:65:D0:28:91:37:
51:       Prime P Exponent
02:40:    x02 == ASN.1 integer, Value Length == 64 bytes
2B:A2:0A:A6:92:8B:76:63:1F:A3:3F:CE:70:34:3D:B1:
21:BB:1B:14:9F:B0:55:BF:93:A7:71:45:27:CC:AB:91:
9A:70:2F:88:EE:42:55:4D:D1:76:E9:B7:74:93:0F:C9:
D7:04:13:0A:E2:D1:81:27:63:64:95:E6:F5:95:73:CD:
          Prime Q Exponent
02:40:    x02 == ASN.1 integer, Value Length == 64 bytes
7E:37:B8:16:EC:87:3E:E3:BB:70:DD:57:29:07:16:B4:
44:95:00:7E:7F:46:0C:2B:70:1D:ED:EB:BE:BA:CD:30:
74:BA:CE:3A:85:CF:D1:3E:B4:07:F6:CC:4E:8F:2B:74:
C6:BA:5D:4F:F4:C3:FC:3C:16:C3:AA:A3:13:58:DB:75
          CRT Coefficient

类似职位:

参考资料:

埃里克森
static KeyPair demo(InputStream pub, InputStream pvt) throws IOException, GeneralSecurityException {
    KeyFactory f = KeyFactory.getInstance("RSA");

    RSAPublicKeySpec pubspec = decodeRSAPublicSSH(readAllBase64Bytes(pub));
    RSAPrivateCrtKeySpec pvtspec = decodeRSAPrivatePKCS1(readAllBase64Bytes(pvt));

    return new KeyPair(f.generatePublic(pubspec), f.generatePrivate(pvtspec));
}

static RSAPublicKeySpec decodeOpenSSH(byte[] input) {
    String[] fields = new String(input, StandardCharsets.US_ASCII).split(" ");
    if ((fields.length < 2) || (!fields[0].equals("ssh-rsa"))) throw new IllegalArgumentException("Unsupported type");
    byte[] std = Base64.getDecoder().decode(fields[1]);
    return decodeRSAPublicSSH(std);
}

static RSAPublicKeySpec decodeRSAPublicSSH(byte[] encoded) {
    ByteBuffer input = ByteBuffer.wrap(encoded);
    String type = string(input);
    if (!"ssh-rsa".equals(type)) throw new IllegalArgumentException("Unsupported type");
    BigInteger exp = sshint(input);
    BigInteger mod = sshint(input);
    if (input.hasRemaining()) throw new IllegalArgumentException("Excess data");
    return new RSAPublicKeySpec(mod, exp);
}

static RSAPrivateCrtKeySpec decodeRSAPrivatePKCS1(byte[] encoded) {
    ByteBuffer input = ByteBuffer.wrap(encoded);
    if (der(input, 0x30) != input.remaining()) throw new IllegalArgumentException("Excess data");
    if (!BigInteger.ZERO.equals(derint(input))) throw new IllegalArgumentException("Unsupported version");
    BigInteger n = derint(input);
    BigInteger e = derint(input);
    BigInteger d = derint(input);
    BigInteger p = derint(input);
    BigInteger q = derint(input);
    BigInteger ep = derint(input);
    BigInteger eq = derint(input);
    BigInteger c = derint(input);
    return new RSAPrivateCrtKeySpec(n, e, d, p, q, ep, eq, c);
}

private static String string(ByteBuffer buf) {
    return new String(lenval(buf), Charset.forName("US-ASCII"));
}

private static BigInteger sshint(ByteBuffer buf) {
    return new BigInteger(+1, lenval(buf));
}

private static byte[] lenval(ByteBuffer buf) {
    byte[] copy = new byte[buf.getInt()];
    buf.get(copy);
    return copy;
}

private static BigInteger derint(ByteBuffer input) {
    int len = der(input, 0x02);
    byte[] value = new byte[len];
    input.get(value);
    return new BigInteger(+1, value);
}

private static int der(ByteBuffer input, int exp) {
    int tag = input.get() & 0xFF;
    if (tag != exp) throw new IllegalArgumentException("Unexpected tag");
    int n = input.get() & 0xFF;
    if (n < 128) return n;
    n &= 0x7F;
    if ((n < 1) || (n > 2)) throw new IllegalArgumentException("Invalid length");
    int len = 0;
    while (n-- > 0) {
        len <<= 8;
        len |= input.get() & 0xFF;
    }
    return len;
}

private static byte[] readAllBase64Bytes(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    BufferedReader r = new BufferedReader(new InputStreamReader(input, StandardCharsets.US_ASCII));
    Decoder decoder = Base64.getDecoder();
    while (true) {
        String line = r.readLine();
        if (line == null) break;
        if (line.startsWith("-----")) continue;
        output.write(decoder.decode(line));
    }
    return output.toByteArray();
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将Graphite JSON输出数组转换为Rickshaw Graph兼容格式

来自分类Dev

无法将time.struct_time转换为JSON兼容格式

来自分类Dev

将Android Intent Filter转换为Xamarin.Android兼容格式

来自分类Dev

无法将time.struct_time转换为JSON兼容格式

来自分类Dev

将python加密EC密钥转换为OpenSSH格式

来自分类Dev

将RSA转换为OPENSSH

来自分类Dev

将WMA转换为Apple生态系统兼容格式(mp3,m4a,aac)

来自分类Dev

如何将Filezilla PPK转换为openssh sftp兼容密钥

来自分类Dev

python将RSA密钥(PEM格式)转换为十六进制字符串

来自分类Dev

如何将PEM密钥转换为RSA密钥对?

来自分类Dev

使用NodeJs Crypto将Java加密转换为Javascript

来自分类Dev

将RSACryptoServiceProvider RSA XML密钥转换为PKCS8

来自分类Dev

OpenSSL使用RSA专用密钥将PEM转换为PFX

来自分类Dev

如何正确地将字符串中的转义符转义以在C中获得JSON兼容格式?

来自分类Dev

将RSA公钥转换为PEM格式

来自分类Dev

将RSA公钥转换为PEM格式

来自分类Dev

Java RSA实现:javax.crypto.BadPaddingException

来自分类Dev

将公共密钥与Crypto ++的ECDH类配合使用

来自分类Dev

如何将TIMESTAMPS格式转换为与Impala兼容

来自分类Dev

将OpenSSH私钥转换为SSH2私钥

来自分类Dev

将OpenSSH私钥转换为SSH2私钥

来自分类Dev

无法将外部Windows Crypto API调用从C#转换为F#

来自分类Dev

将 crypto.subtle.deriveKey 结果转换为十六进制字符串

来自分类Dev

如何以OpenSSH的新密钥格式存储RSA-4096 SSH密钥

来自分类Dev

将Pem rsa密钥转换为C#RSACryptoServiceProvider.FromXmlString的xml

来自分类Dev

将RSA pem密钥字符串转换为der字节[]

来自分类Dev

将RSA pem密钥字符串转换为der字节[]

来自分类Dev

以Handsontable兼容格式返回MVC Json

来自分类Dev

从RDBMS导出到Hadoop兼容格式

Related 相关文章

  1. 1

    将Graphite JSON输出数组转换为Rickshaw Graph兼容格式

  2. 2

    无法将time.struct_time转换为JSON兼容格式

  3. 3

    将Android Intent Filter转换为Xamarin.Android兼容格式

  4. 4

    无法将time.struct_time转换为JSON兼容格式

  5. 5

    将python加密EC密钥转换为OpenSSH格式

  6. 6

    将RSA转换为OPENSSH

  7. 7

    将WMA转换为Apple生态系统兼容格式(mp3,m4a,aac)

  8. 8

    如何将Filezilla PPK转换为openssh sftp兼容密钥

  9. 9

    python将RSA密钥(PEM格式)转换为十六进制字符串

  10. 10

    如何将PEM密钥转换为RSA密钥对?

  11. 11

    使用NodeJs Crypto将Java加密转换为Javascript

  12. 12

    将RSACryptoServiceProvider RSA XML密钥转换为PKCS8

  13. 13

    OpenSSL使用RSA专用密钥将PEM转换为PFX

  14. 14

    如何正确地将字符串中的转义符转义以在C中获得JSON兼容格式?

  15. 15

    将RSA公钥转换为PEM格式

  16. 16

    将RSA公钥转换为PEM格式

  17. 17

    Java RSA实现:javax.crypto.BadPaddingException

  18. 18

    将公共密钥与Crypto ++的ECDH类配合使用

  19. 19

    如何将TIMESTAMPS格式转换为与Impala兼容

  20. 20

    将OpenSSH私钥转换为SSH2私钥

  21. 21

    将OpenSSH私钥转换为SSH2私钥

  22. 22

    无法将外部Windows Crypto API调用从C#转换为F#

  23. 23

    将 crypto.subtle.deriveKey 结果转换为十六进制字符串

  24. 24

    如何以OpenSSH的新密钥格式存储RSA-4096 SSH密钥

  25. 25

    将Pem rsa密钥转换为C#RSACryptoServiceProvider.FromXmlString的xml

  26. 26

    将RSA pem密钥字符串转换为der字节[]

  27. 27

    将RSA pem密钥字符串转换为der字节[]

  28. 28

    以Handsontable兼容格式返回MVC Json

  29. 29

    从RDBMS导出到Hadoop兼容格式

热门标签

归档