Java ssh-rsa字符串到公钥 [英] Java ssh-rsa string to public key

查看:49
本文介绍了Java ssh-rsa字符串到公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取 .pub 文件内容的公共密钥.这是一个 .pub 文件内容的示例(由 ssh-keygen 生成):

<预> <代码> SSH-RSA AAAAB3NzaC1yc2EAAAADAQABAAACAQDBPL2s + 25Ank3zS6iHUoVk0tS63dZM0LzAaniiDon0tdWwq4vcL4 + fV8BsAEcpMeijS92JhDDc9FccXlHbdDcmd6c4ITOt9h9xxhIefGsi1FTVJ/EjVtbqF5m0bu7ruIMGvuP1p5s004roHx9y0UdHvD/yNWLISMhy4nio6jLailIj3FS53Emj1WRNsOrpja3LzPXzhuuj6YnD9yfByT7iGZipxkmleaXrknChPClLI9uhcqtAzBLdd0NVTJLOt/3 + d1cSNwdBw9e53wJvpEmH + P8UOZd + OV/y7cHIej4jQpBXVvpJR1Yaluh5RuxY90B0hSescUAj4g/3HVPpR/gE7op6i9Ab//0iXF15uWGlGzipI4lA2/wYEtv8swTjmdCTMNcTDw/1huTDEzZjghIKVpskHde/Lj416c7eSByLqsMg2OhlZGChKznpIjhuNRXz93DwqKuIKvJKSnhqaJDxmDGfG7nlQ/eTwGeAZ6VR50yMPiRTIpuYd767 + Nsg486z7p0pnKoBlL6ffTbfeolUX2b6Nb9ZIOxJdpCSNTQRKQ50p4Y3S580cUM1Y2EfjlfIQG1JdmTQYB75AZXi/cB2PvScmF0bXRoj7iHg4lCnSUvRprWA0xbwzCW/wjNqw6MyRX42FFlvSRrmfaxGZxKYbmk3TzBv +Fp + CADPqQm3OQ == test@test.com

如果我是对的,那么这不是公共密钥,但是可以从此字符串中获取公共密钥.

此答案回答了我的问题 https://stackoverflow.com/a/19387517/2735398
但是答案似乎不起作用.我有一个例外:

  java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:无效的密钥格式 

在查看答案的评论时,我不是唯一有问题的人...

如何解决该异常?还是从字符串中获取公钥的另一种方法?

解决方案

这是我的SSH RSA-> RSAPublicKey转换器实现.我已经在网络中的某个地方找到了关键格式描述,所以要感谢提供它的人.

 公共类CertificateUtils {私有静态最终int VALUE_LENGTH = 4;私有静态最终字节[] INITIAL_PREFIX =新字节[] {0x00、0x00、0x00、0x07、0x73、0x73、0x68、0x2d,0x72、0x73、0x61};私有静态最终模式SSH_RSA_PATTERN = Pattern.compile("ssh-rsa [\\ s] +([[A-Za-z0-9/+] + = *)[\\ s] +.*");//SSH-RSA密钥格式////00 00 00 07下一个字段的长度(以字节为单位)//73 73 68 2d 72 73 61密钥类型("ssh-rsa"的ASCII编码)//00 00 00 03公共指数的长度(以字节为单位)//01 00 01公共指数(通常为65537,如此处所示)//00 00 01 01模数的长度(以257为单位)//00 c3 a3 ...模数公共静态RSAPublicKey parseSSHPublicKey(String key)引发InvalidKeyException {匹配器匹配器= SSH_RSA_PATTERN.matcher(key.trim());如果(!matcher.matches()){抛出新的InvalidKeyException(密钥格式对于SSH RSA无效.");}字符串keyStr = matcher.group(1);ByteArrayInputStream是= new ByteArrayInputStream(Base64.decodeBase64(keyStr));byte []前缀=新字节[INITIAL_PREFIX.length];尝试 {if(INITIAL_PREFIX.length!= is.read(prefix)||!ArrayUtils.isEquals(INITIAL_PREFIX,前缀)){抛出新的InvalidKeyException(缺少初始[ssh-rsa]键前缀.");}BigInteger指数= getValue(is);BigInteger模数= getValue(is);返回(RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus,exponent));} catch(IOException | InvalidKeySpecException | NoSuchAlgorithmException e){抛出新的InvalidKeyException(无法从字符串读取SSH RSA证书",e);}}私有静态BigInteger getValue(InputStream is)引发IOException {byte [] lenBuff =新的byte [VALUE_LENGTH];如果(VALUE_LENGTH!= is.read(lenBuff)){抛出新的InvalidParameterException(无法读取值长度.");}int len = ByteBuffer.wrap(lenBuff).getInt();byte [] valueArray =新的byte [len];如果(len!= is.read(valueArray)){抛出新的InvalidParameterException(无法读取值.");}返回新的BigInteger(valueArray);}} 

希望这会有所帮助.

I want to get the public key of the content of an .pub file. This is an example what the content of a .pub file looks like(generated with ssh-keygen):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDBPL2s+25Ank3zS6iHUoVk0tS63dZM0LzAaniiDon0tdWwq4vcL4+fV8BsAEcpMeijS92JhDDc9FccXlHbdDcmd6c4ITOt9h9xxhIefGsi1FTVJ/EjVtbqF5m0bu7ruIMGvuP1p5s004roHx9y0UdHvD/yNWLISMhy4nio6jLailIj3FS53Emj1WRNsOrpja3LzPXzhuuj6YnD9yfByT7iGZipxkmleaXrknChPClLI9uhcqtAzBLdd0NVTJLOt/3+d1cSNwdBw9e53wJvpEmH+P8UOZd+oV/y7cHIej4jQpBXVvpJR1Yaluh5RuxY90B0hSescUAj4g/3HVPpR/gE7op6i9Ab//0iXF15uWGlGzipI4lA2/wYEtv8swTjmdCTMNcTDw/1huTDEzZjghIKVpskHde/Lj416c7eSByLqsMg2OhlZGChKznpIjhuNRXz93DwqKuIKvJKSnhqaJDxmDGfG7nlQ/eTwGeAZ6VR50yMPiRTIpuYd767+Nsg486z7p0pnKoBlL6ffTbfeolUX2b6Nb9ZIOxJdpCSNTQRKQ50p4Y3S580cUM1Y2EfjlfIQG1JdmTQYB75AZXi/cB2PvScmF0bXRoj7iHg4lCnSUvRprWA0xbwzCW/wjNqw6MyRX42FFlvSRrmfaxGZxKYbmk3TzBv+Fp+CADPqQm3OQ== test@test.com

If I am right this is not the public key, but it is possible to get the public key from this string.

This answer gives answer to my question https://stackoverflow.com/a/19387517/2735398
But the answer doesn't seem to work. I get an exception:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format

When looking at the comments of the answer I am not the only person with the problem...

How can I fix the exception? Or is there another way to get the public key from the string?

解决方案

Here is my SSH RSA -> RSAPublicKey converter implementation. I've found key format description somewhere in the net, so thanks to the one who provided it.

public class CertificateUtils {
    private static final int VALUE_LENGTH = 4;
    private static final byte[] INITIAL_PREFIX = new byte[]{0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61};
    private static final Pattern SSH_RSA_PATTERN = Pattern.compile("ssh-rsa[\\s]+([A-Za-z0-9/+]+=*)[\\s]+.*");

// SSH-RSA key format
//
//        00 00 00 07             The length in bytes of the next field
//        73 73 68 2d 72 73 61    The key type (ASCII encoding of "ssh-rsa")
//        00 00 00 03             The length in bytes of the public exponent
//        01 00 01                The public exponent (usually 65537, as here)
//        00 00 01 01             The length in bytes of the modulus (here, 257)
//        00 c3 a3...             The modulus

    public static RSAPublicKey parseSSHPublicKey(String key) throws InvalidKeyException {
        Matcher matcher = SSH_RSA_PATTERN.matcher(key.trim());
        if (!matcher.matches()) {
            throw new InvalidKeyException("Key format is invalid for SSH RSA.");
        }
        String keyStr = matcher.group(1);

        ByteArrayInputStream is = new ByteArrayInputStream(Base64.decodeBase64(keyStr));

        byte[] prefix = new byte[INITIAL_PREFIX.length];

        try {
            if (INITIAL_PREFIX.length != is.read(prefix) || !ArrayUtils.isEquals(INITIAL_PREFIX, prefix)) {
                throw new InvalidKeyException("Initial [ssh-rsa] key prefix missed.");
            }

            BigInteger exponent = getValue(is);
            BigInteger modulus = getValue(is);

            return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));
        } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) {
            throw new InvalidKeyException("Failed to read SSH RSA certificate from string", e);
        }
    }

    private static BigInteger getValue(InputStream is) throws IOException {
        byte[] lenBuff = new byte[VALUE_LENGTH];
        if (VALUE_LENGTH != is.read(lenBuff)) {
            throw new InvalidParameterException("Unable to read value length.");
        }

        int len = ByteBuffer.wrap(lenBuff).getInt();
        byte[] valueArray = new byte[len];
        if (len != is.read(valueArray)) {
            throw new InvalidParameterException("Unable to read value.");
        }

        return new BigInteger(valueArray);
    }
}

Hope this helps.

这篇关于Java ssh-rsa字符串到公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆