InvalidKeySpecException using public key

2019-05-21 04:02发布

问题:

I'm desperately trying to encrypt a message using asymmetric public / private key cryptography on an Android.

I'm on Windows and I've generated a public and private key using puttygen. I'm not sure what difference it makes but I've selected SSH-2 RSA. Here is the public key:

AAAAB3NzaC1yc2EAAAABJQAAAQEAh63orUzl0UTd7jj0KNYJg1+kNnty0QHyJu0r
Cajf5Kl7qWJaGXPfwsG8Qt3teafs5sv0JBSinab0s/5wfQmd1QPpXTMP93Wc4ucp
1VC/9B2o8XVi4fKoGTehB48yrSfI6KF2AIeASM1jUswydKxsuS4AS2mLGV/HuoKD
huMfCsRc8qK5zGQfVCoZTbQ66Z1yKdAzxMUuGmiTp7pVsle/P/UGbm6yFiee5r1/
dOR2CDyR6CP09Jaj7KSGfGuwPryCXPjEce1oCbN/FlLHVb7T1B5f6xhq+oY+Ij13
1IZPfShV8cs2kYKjsle2s23V5urSdWFv2tEcSJcpkUm2FlPdQw==

I've copied this to a text file in my main/assets folder. I read this in like so:

InputStream input = context.getAssets().open(filename);

This is then read in to a byte array through a fairly standard ByteArrayOutputStream method.

I then try and convert that to a public key as such:

public static PublicKey getPublicKey(byte[] keyBytes){
    PublicKey publicKey = null;

    if(keyBytes != null) {

        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = null;
        try {
            kf = KeyFactory.getInstance("RSA");
            publicKey = kf.generatePublic(spec);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "NoSuchAlgorithmException");
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            Log.e(TAG, "InvalidKeySpecException " + e.getMessage());
            e.printStackTrace();
        }
    }

    return publicKey;
}

Problem is I keep getting this error:

InvalidKeySpecException java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

I've been attacking this for hours, and can't seem to get around it. Please please any suggestions welcome.

I've tried Base64 as such:

byte[] tempNewKey = Base64.decode(keyBytes, Base64.DEFAULT);

Which makes no difference and I've also tried using

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(module), new BigInteger(exponent));

However putty doesn't tell me anything about an exponent? If I go ahead with this method I don't get the same error, but if I try and decrypt with my private key I just get gibberish.

Really hope you can help. Many Thanks

回答1:

SSH keys are not X509 compatible keys. They are stored in a SSH proprietary format. You'll need a SSH capable libary to retrieve the key value.

If SSH functionality is not required then it is possible to generate keys in Java (using the keytool command line or KeyPairGenerator.

Alternatively it is also possible to use external applications or libraries such as the openssl command line. In the case of OpenSSL specify DER as output. Java expects a DER encoded SubjectPublicKeyInfo structure for X509EncodedKeySpec.