RSA Encryption / Decryption using Java

27,551

Your problem is indeed with the padding. Some kind of padding, either PKCS#1 1.5 or OAEP padding in practice, is required for secure RSA functionality. Furthermore, it is required to find the start and end of the encrypted plain text.

The modular exponentiation of RSA is performed using large integers. The results of these operations are then represented as octet strings. These octet strings are basically big endian, unsigned, fixed length representation of an integer. These integers are left padded with 00 valued bytes (this is called the I2OS primitive in the RSA standard). So what you are seeing is the result of the modular exponentiation, with the 00 padding still in place.

Long story short, always use a padding scheme. Nowadays, OAEP would be preferable. Use it together with hybrid encryption scheme, or use a higher level container format such as CMS or PGP.

Share:
27,551
user2192774
Author by

user2192774

Updated on May 22, 2020

Comments

  • user2192774
    user2192774 about 4 years

    I am doing a simple program to encrypt/decrypt using RSA algorithm in Java. I create a cipher object as follows:

    //Create a Cipher object
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
    

    I do the encryption by calling the encrypt function:

    String cipher=encrypt(textByte, pair, rsaCipher);
    System.out.println("The Encryption using RSA Algorithm : "+cipher);
    

    And the decryption as:

    //Decryption
    String plain=decrypt(Base64.decodeBase64(cipher),pair, rsaCipher);
    System.out.println("The Decryption using RSA Algorithm : "+plain);
    

    When I display the output, the decryption output returns a long space before the original text: enter image description here

    However, when I edit the code for creating the Cipher object to be: //Create a Cipher object Cipher rsaCipher = Cipher.getInstance("RSA");

    i.e, removed the operation mode and padding arguments, the problem get resolved and the output becomes: enter image description here

    Where is the problem. In the first case (when the space appears), I specified NoPadding? Why the spaces appears in the decrypted message ? Even if I used padding, I expect this should not happen.

    EDIT: This is the encrypt and decrypt methods:

    public static String encrypt(byte[] textBytes, KeyPair pair, Cipher rsaCipher) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
        //get the public key
        PublicKey pk=pair.getPublic(); 
    
    
        //Initialize the cipher for encryption. Use the public key.
        rsaCipher.init(Cipher.ENCRYPT_MODE, pk);
    
        //Perform the encryption using doFinal
        byte[] encByte = rsaCipher.doFinal(textBytes);
    
        // converts to base64 for easier display.
        byte[] base64Cipher = Base64.encodeBase64(encByte);
    
        return new String(base64Cipher);
    }//end encrypt
    
    public static String decrypt(byte[] cipherBytes, KeyPair pair, Cipher rsaCipher) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException
    {
        //get the public key
        PrivateKey pvk=pair.getPrivate(); 
    
        //Create a Cipher object
        //Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
    
        //Initialize the cipher for encryption. Use the public key.
        rsaCipher.init(Cipher.DECRYPT_MODE, pvk);
    
        //Perform the encryption using doFinal
        byte[] decByte = rsaCipher.doFinal(cipherBytes);
    
        return new String(decByte);
    
    }//end decrypt