0

Im trying to encrypt and decrypt a string, and eventually a file containing plaintext, using my own RSA implementation in Java. Ive tried following countless examples here on SO and the web, where people are using either the built in Java RSA function or their own implementation of the algorithm, but cant get any of them to work, in that the decrypted text never matches the original string.

I dont know if i am doing something wrong with the encoding/decoding of text, have tried using default UTF-8 and the Base64 encoders in java.xml.* but no luck there either. Im not using any padding, i dont know if thats necessary for it work at all, and im just using an arbitrary key length, which ive tried changing the size of, and doesnt make things work either. This is just an exercise for myself, no ones information is going to be protected by this or anything. But im not sure what the issue is, so here is my code, that tries to encrypt/decrypt a simple string:

   BigInteger ONE = new BigInteger("1");
   SecureRandom rand = new SecureRandom();

   BigInteger d;
   BigInteger e;
   BigInteger n;
   BigInteger p = BigInteger.probablePrime(10, rand); // 10 is arbitrary, have tried different numbers
   BigInteger q = BigInteger.probablePrime(10, rand);
   BigInteger phi = (p.subtract(ONE)).multiply(q.subtract(ONE));

   n = p.multiply(q); //10 bits * 10 bits = ??? bits for key length
   e = new BigInteger("65537"); //public key exponent 
   d = e.modInverse(phi); //private key exponent

   String string = "this is a test";
   byte[] bytes = string.getBytes();
   BigInteger plainText = new BigInteger(bytes);
   BigInteger cipherText = plainText.modPow(e, n);
   BigInteger originalMessage = cipherText.modPow(d, e);

   System.out.println(string.getBytes());
   System.out.println(cipherText);
   System.out.println(originalMessage);

The output has different values for all three things everytime i run my program: But they are always in the same relative form:

[B@52d85409
157529
24312

2 Answers 2

1

Several notes:

  1. Your modulus (the n in your example) needs to be as least as long as the amount of information you want to encrypt. This is one of the caveats of RSA, which is why things like AES are better suited for longer streams like files. Below I have chosen 128 for the range of p and q instead of 10, other values could work as well.
  2. It's cipherText.modPow(d, n)
  3. You have to convert the BigInteger back to a String to print it properly, so: new String(originalMessage.toByteArray())

Putting it all together:

BigInteger ONE = new BigInteger("1");
SecureRandom rand = new SecureRandom();

BigInteger d, e, n;
BigInteger p = BigInteger.probablePrime(128, rand);
BigInteger q = BigInteger.probablePrime(128, rand);
BigInteger phi = (p.subtract(ONE)).multiply(q.subtract(ONE));

n = p.multiply(q);
e = new BigInteger("65537");
d = e.modInverse(phi);

String string = "this is a test";
BigInteger plainText = new BigInteger(string.getBytes());
BigInteger cipherText = plainText.modPow(e, n);
BigInteger originalMessage = cipherText.modPow(d, n);
String decrypted = new String(originalMessage.toByteArray());

System.out.println("original: " + string);
System.out.println("decrypted: " + decrypted);
Sign up to request clarification or add additional context in comments.

1 Comment

The new Sting(byte[]) constructor and the String.getBytes() method use the default character encoding, which varies from system to system. You need to specify the encoding explicitly. (When in doubt, UTF-8.)
0

Yes, but the E should be a random number that is relatively prime to phi. So, E should equal something like this:

    BigInteger e = new BigInteger("65537"); //to make the compiler happy
    BigInteger counter = (BigInteger.probablePrime(128, random)).mod(phi);
    while(counter.intValue() > 2)
    {
        if((e.gcd(phi)).intValue() == 1)
        {
            e = counter;
            break;
        }
        counter = counter.subtract(BigInteger.ONE);
    }

Also, the maximun amount of characters you can enter is 32 before the decryption doesn't work. So be careful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.