2

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

James
  • 3,485
  • 3
  • 20
  • 43
  • Do you need to use SSH keys? SSH keys are not X509 encoded, so unless you use a SSH compatible library, you may be trying forever... You could either generate the keys in Java itself or alternatively use OpenSSL DER encoded keys. – Maarten Bodewes Jan 29 '15 at 16:38
  • Hi Maarten, thanks so much for helping. No, no need to use SSH, any private / public key will do. I tried create a key as you say using keytool -genkey etc. This seemed to work but the error in my code is still the same? – James Jan 29 '15 at 17:37
  • It's a rather generic exception. Without more info it is difficult to see what is the cause of the error *this time around*. Wait a moment, I'll answer this question and then you can ask a new one, otherwise the question will not be specific. – Maarten Bodewes Jan 29 '15 at 17:53
  • My advice to anyone doing this is note what Maarten says that SSH keys won't work. You need to download openssl and then follow these steps to generate an SSL public / private key in a java ready format: http://stackoverflow.com/a/19387517/3009199 – James Jan 30 '15 at 14:19

1 Answers1

0

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.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263