3

I am implementing RSA in java I have encountered a code which is given below it is showing plaintext in numeric form after decrypting the plaintext, but I want it in simple english which I entered. I don't want to use the java api.

TestRsa.Java

import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;

public class TestRsa {

    private BigInteger p, q;
    private BigInteger n;
    private BigInteger PhiN;
    private BigInteger e, d;

    public TestRsa() {
        initialize();
    }

    public void initialize() {
        int SIZE = 512;
        /* Step 1: Select two large prime numbers. Say p and q. */
        p = new BigInteger(SIZE, 15, new Random());
        q = new BigInteger(SIZE, 15, new Random());
        /* Step 2: Calculate n = p.q */
        n = p.multiply(q);
        /* Step 3: Calculate ø(n) = (p - 1).(q - 1) */
        PhiN = p.subtract(BigInteger.valueOf(1));
        PhiN = PhiN.multiply(q.subtract(BigInteger.valueOf(1)));
        /* Step 4: Find e such that gcd(e, ø(n)) = 1 ; 1 < e < ø(n) */
        do {
            e = new BigInteger(2 * SIZE, new Random());
        } while ((e.compareTo(PhiN) != 1)
                || (e.gcd(PhiN).compareTo(BigInteger.valueOf(1)) != 0));
        /* Step 5: Calculate d such that e.d = 1 (mod ø(n)) */
        d = e.modInverse(PhiN);
    }

    public BigInteger encrypt(BigInteger plaintext) {
        return plaintext.modPow(e, n);
    }

    public BigInteger decrypt(BigInteger ciphertext) {
        return ciphertext.modPow(d, n);
    }

    public static void main(String[] args) throws IOException {
        TestRsa app = new TestRsa();
        int plaintext;
        System.out.println("Enter any character : ");
        plaintext = System.in.read();
        BigInteger bplaintext, bciphertext;
        bplaintext = BigInteger.valueOf((long) plaintext);
        bciphertext = app.encrypt(bplaintext);
        System.out.println("Plaintext : " + bplaintext.toString());
        System.out.println("Ciphertext : " + bciphertext.toString());
        bplaintext = app.decrypt(bciphertext);
        System.out.println("After Decryption Plaintext : "
                + bplaintext.toString());
    }
}
2
  • 2
    -1 for posting code that is more than 50% blank lines. If you want people to read your code, it's up to you to make it readable. Commented Jul 31, 2014 at 6:18
  • P & Q are not tested for primality? Commented May 25, 2022 at 1:13

4 Answers 4

6

My RSA Class:

package com.infovale.cripto;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class RSA {


static String kPublic = "";
static String kPrivate = "";

public RSA()
{

}


public String Encrypt(String plain) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException {

    String encrypted;
    byte[] encryptedBytes;      

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(1024);
    KeyPair kp = kpg.genKeyPair();

    PublicKey publicKey = kp.getPublic();
    PrivateKey privateKey = kp.getPrivate();

    byte[] publicKeyBytes = publicKey.getEncoded();
    byte[] privateKeyBytes = privateKey.getEncoded();

    kPublic = bytesToString(publicKeyBytes);
    kPrivate = bytesToString(privateKeyBytes);

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    encryptedBytes = cipher.doFinal(plain.getBytes());

    encrypted = bytesToString(encryptedBytes);
    return encrypted;

}

public String Decrypt(String result) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException {

    byte[] decryptedBytes;

    byte[] byteKeyPrivate = stringToBytes(kPrivate);

    KeyFactory kf = KeyFactory.getInstance("RSA");

    PrivateKey privateKey = null;
    try {

        privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(byteKeyPrivate));

    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }

    String decrypted;

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    decryptedBytes = cipher.doFinal(stringToBytes(result));
    decrypted = new String(decryptedBytes);
    return decrypted;

}

public String bytesToString(byte[] b) {
    byte[] b2 = new byte[b.length + 1];
    b2[0] = 1;
    System.arraycopy(b, 0, b2, 1, b.length);
    return new BigInteger(b2).toString(36);
}

public byte[] stringToBytes(String s) {
    byte[] b2 = new BigInteger(s, 36).toByteArray();
    return Arrays.copyOfRange(b2, 1, b2.length);
}
}
Sign up to request clarification or add additional context in comments.

1 Comment

the op wrote: "I don't want to use the java api"
1

try these lines:

System.out.println("Plaintext : " +  new String(bplaintext.toByteArray() ) );
System.out.println("Ciphertext : " +  new String(bciphertext.toByteArray() ) );
bplaintext = app.decrypt(bciphertext);
        System.out.println("After Decryption Plaintext : " + new String(bplaintext.toByteArray() ) );

Comments

0

I edited Elton Da Costa's class a little bit adding that feature to convert Public key from String to PublicKey class. Because the user of this class might ultimately want to give out the public key to a third party for encryption of the message and keep the private key with himself for decryption.

            package com.custom.util;

            import java.math.BigInteger;
            import java.security.InvalidKeyException;
            import java.security.KeyFactory;
            import java.security.KeyPair;
            import java.security.KeyPairGenerator;
            import java.security.NoSuchAlgorithmException;
            import java.security.PrivateKey;
            import java.security.PublicKey;
            import java.security.spec.InvalidKeySpecException;
            import java.security.spec.PKCS8EncodedKeySpec;
            import java.security.spec.X509EncodedKeySpec;
            import java.util.Arrays;

            import javax.crypto.BadPaddingException;
            import javax.crypto.Cipher;
            import javax.crypto.IllegalBlockSizeException;
            import javax.crypto.NoSuchPaddingException;

            public class RSA {

                static String kPublic = "";
                static String kPrivate = "";

                public RSA() {

                }

                public class KeyPairStrings {
                    private String pubKey;
                    private String privKey;

                    public String getPubKey() {
                        return pubKey;
                    }

                    public String getPrivKey() {
                        return privKey;
                    }

                    @Override
                    public String toString() {
                        return "KeyPairStrings [pubKey=" + pubKey + ", privKey=" + privKey + "]";
                    }



                }

            public KeyPairStrings getKeyPair() throws NoSuchAlgorithmException{

                KeyPairStrings keyPairStrings = new RSA.KeyPairStrings();

                KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                kpg.initialize(1024);
                KeyPair kp = kpg.genKeyPair();

                PublicKey publicKey = kp.getPublic();
                PrivateKey privateKey = kp.getPrivate();

                byte[] publicKeyBytes = publicKey.getEncoded();
                byte[] privateKeyBytes = privateKey.getEncoded();

                keyPairStrings.pubKey = bytesToString(publicKeyBytes);
                keyPairStrings.privKey = bytesToString(privateKeyBytes);

                return keyPairStrings ;
            }


            public String encrypt(String text , String pubKey) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException{

                byte[] pubKeyByte = stringToBytes(pubKey) ;

                KeyFactory kf = KeyFactory.getInstance("RSA");

                PublicKey publicKey = null;
                try {

                    publicKey = kf.generatePublic(new X509EncodedKeySpec(pubKeyByte));

                } catch (InvalidKeySpecException e) {
                    e.printStackTrace();
                }

                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, publicKey );
                byte[] encryptedBytes = cipher.doFinal(text.getBytes());

                String encrypted = bytesToString(encryptedBytes);

                return encrypted;
            }

            public String decrypt(String encryptedText , String privKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{

                byte[] privKeyByte = stringToBytes(privKey) ;

                KeyFactory kf = KeyFactory.getInstance("RSA");

                PrivateKey privateKey = null;
                try {

                    privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(privKeyByte));

                } catch (InvalidKeySpecException e) {
                    e.printStackTrace();
                }

                String decrypted;

                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] decryptedBytes = cipher.doFinal(stringToBytes(encryptedText));
                decrypted = new String(decryptedBytes);
                return decrypted;
            }


            public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {

                String text = "hello" ;

                RSA rsa = new RSA();

                KeyPairStrings keyPairStrings =  rsa.getKeyPair() ;

                System.out.println(keyPairStrings);

                String encrypted  = rsa.encrypt(text, keyPairStrings.getPubKey());

                System.out.println("encrypted : "+encrypted);   

                String textResult = rsa.decrypt(encrypted, keyPairStrings.getPrivKey());

                System.out.println("textResult : "+textResult);

            }



                public static String bytesToString(byte[] b) {
                    byte[] b2 = new byte[b.length + 1];
                    b2[0] = 1;
                    System.arraycopy(b, 0, b2, 1, b.length);
                    return new BigInteger(b2).toString(36);
                }

                public byte[] stringToBytes(String s) {
                    byte[] b2 = new BigInteger(s, 36).toByteArray();
                    return Arrays.copyOfRange(b2, 1, b2.length);
                }
            }

Comments

0

Instead of this (which only reads the first character):

int plaintext;
plaintext = System.in.read();
bplaintext = BigInteger.valueOf((long) plaintext);

Use this (to read the string):

byte[] plaintext;
plaintext = new Scanner(System.in).nextLine().getBytes();
bplaintext = new BigInteger(plaintext);

Then add this to the end (to convert the decrypted BigInteger back to a string)

System.out.println("Original String: " + new String(bplaintext.toByteArray()));

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.