3

I'm working on an android application where I'd like the user to be able to encrypt messages using other's public keys. The system would generate a public/private keypair and then messages can be sent to other users secretly.

I'm creating an Encryption class which will handle the encryption/decryption of messages. Unfortunately I'm having some problems.

In this method, I'd like to pass the user's secret (private key) as well as the message they want to encrypt. I'd like the secret to be user-defined (like "MySecretPassword").

public static void lock(String secret, String textToEncrypt) {
    try {
        //Convert the public key string into a key
        byte[] encodedPublicKey = Base64.decode(secret.getBytes("utf-8"),Base64.DEFAULT);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedPublicKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publickey = keyFactory.generatePublic(spec); //Crash Here
        PrivateKey privateKey = keyFactory.generatePrivate(spec);

        //Encrypt Message
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publickey);
        byte[] encryptedBytes = cipher.doFinal(textToEncrypt.getBytes());
        Log.d(TAG,"Encrypted: "+new String(encryptedBytes));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The exception is as follows:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0c0740b0:ASN.1 encoding routines:ASN1_get_object:TOO_LONG

What am I missing here? Am I missing something obvious or am I misunderstanding how these tools work? I've used this javascript library for public/private key encryption before and am trying to do something similar here. I'd appreciate it if somebody could point me in the right direction :)

3
  • 1
    "Other users messages can be decrypted using their public key." So they aren't secret because everybody knows the public key? Your error: you don't want to generate a key based on X509 encoded data, you want to generate one based on a password: stackoverflow.com/a/992413/995891
    – zapl
    Commented May 11, 2016 at 21:45
  • Ah, I mixed things up while typing. The user should encrypt a message using their target's public key (e.g. if I want to send a message to my friend, I encrypt using that friends public key). I'll take a look at the link you posted :)
    – Pancake
    Commented May 11, 2016 at 21:50
  • 1
    Maybe it's just a typo but the public key is known to everybody, you can encrypt data with it, which only the receiver (= owner of the private key) can decrypt. That's the way it's secure to send messages. edit: yep.
    – zapl
    Commented May 11, 2016 at 21:52

1 Answer 1

2

A secret is not a public key.

You encrypt with the public key of the recipient. That value is public, which means that anybody can look it up. You need to get the value of the other party's public key and feed it into your code, not send in your own private key. The proper way to do this does not involve any secrets!

Normally one does not directly encrypt a message with RSA, instead they encrypt an AES key (or other symmetric key) with RSA and use the AES key to encrypt the message. If your messages are really short, you could use RSA directly, but it won't work for long messages.

Here are a couple links showing how to implement RSA on Android:

Not the answer you're looking for? Browse other questions tagged or ask your own question.