1

I'm trying to encrypt string using RSA with public Key in java. facing exception like "java.security.InvalidKeyException: invalid key format"

Partial Public key :

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA993qkLy6s+EL5SQ7vqmZ
LBZEV0/tc7T5x8yRJwN0WmWy2TxOnxjFuLvO2b9ai3aEe7X5a6jzl5aE99RXbo86
IB2PDH1dDN+W2IKfQViRyZE8hKRZnLH+QEbbRr3a
x/EVAnC/cObCKgjNY4jp30sCAwEAAQxxxxxxxx==
-----END PUBLIC KEY-----

Note: public key generated and got from client.

Code:

    package com.Test.in;
    
    
    import java.security.KeyFactory;
    import java.security.PublicKey;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    import javax.crypto.Cipher;
    
    
    public class RSA_PublicKey {
        public static final String NEW_LINE_CHARACTER = "\n";
        public static final String PUBLIC_KEY_START_KEY_STRING = "-----BEGIN PUBLIC KEY-----";
        public static final String PUBLIC_KEY_END_KEY_STRING = "-----END PUBLIC KEY-----";
        public static final String EMPTY_STRING = "";
public static final String NEW_CR_CHARACTER = "\r";
        private static final String ALGORITHM = "RSA";
        
        public static void main(String[] args) {
             String pub_Key="-----BEGIN PUBLIC KEY-----\r\n" + 
                "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA993qkLy6s+EL5SQ7vqmZ\r\n" + 
                "LBZEV0/tc7T5x8yRJwN0WmWy2TxOnxjFuLvO2b9ai3aEe7X5a6jzl5aE99RXbo86\r\n" + 
                "IB2PDH1dDN+W2IKfQViRyZE8hKRZnLH+QEbbRr3a\r\n" + 
                "x/EVAnC/cObCKgjNY4jp30sCAwEAAQxxxxxxxx==\r\n" + 
                "-----END PUBLIC KEY-----";
             pub_Key=pub_Key.replaceAll(NEW_LINE_CHARACTER, EMPTY_STRING)
                        .replaceAll(PUBLIC_KEY_START_KEY_STRING, EMPTY_STRING)
                        .replaceAll(PUBLIC_KEY_END_KEY_STRING, EMPTY_STRING).replaceAll(NEW_CR_CHARACTER, EMPTY_STRING);
            
            byte[] publicKey  = pub_Key.getBytes();
            try {
                byte[] encryptedData = encrypt(publicKey,
                        "hi this is Visruth here".getBytes());
                
                String encryptedString = Base64.getEncoder().encodeToString(encryptedData);
                
                System.out.println("Output encryptedString: " + encryptedString);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        public static byte[] encrypt(byte[] publicKey, byte[] inputData)
                throws Exception {
    
            PublicKey key = KeyFactory.getInstance(ALGORITHM)
                    .generatePublic(new X509EncodedKeySpec(publicKey));
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
    
            byte[] encryptedBytes = cipher.doFinal(inputData);
    
            return encryptedBytes;
        }
    }

Facing exception like below.

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source)
    at java.security.KeyFactory.generatePublic(Unknown Source)
    at com.cts.in.Test.RSA_PublicKey.encrypt(RSA_PublicKey.java:63)
    at com.cts.in.Test.RSA_PublicKey.main(RSA_PublicKey.java:44)
Caused by: java.security.InvalidKeyException: invalid key format
    at sun.security.x509.X509Key.decode(Unknown Source)
    at sun.security.x509.X509Key.decode(Unknown Source)
    at sun.security.rsa.RSAPublicKeyImpl.<init>(Unknown Source)
    at sun.security.rsa.RSAKeyFactory.generatePublic(Unknown Source)
    ... 4 more

Reference link 1

reference link 2

May I know the way to achieve this use case(encrypt string using RSA with public Key )?

4
  • Does this help? stackoverflow.com/a/39615507/45112 Commented Feb 16, 2022 at 17:26
  • Hi @armandino I already included that as reference link1. i followed the same approach. facing exceptions by using public key. Commented Feb 16, 2022 at 17:40
  • 1
    In the pub_key string \r is not removed and no Base64 decoding is performed. Commented Feb 16, 2022 at 17:50
  • 2
    You need to base64-decode the public key string after removing the header and footer lines. Commented Feb 16, 2022 at 17:52

1 Answer 1

1

As per suggestion above, I tried to remove \r and performing base64-decode of public key string , getting encrypted value.

Working Code:

package com.Test.in;
    
    
    import java.security.KeyFactory;
    import java.security.PublicKey;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    import javax.crypto.Cipher;
    
    
    public class RSA_PublicKey {
        public static final String NEW_LINE_CHARACTER = "\n";
        public static final String PUBLIC_KEY_START_KEY_STRING = "-----BEGIN PUBLIC KEY-----";
        public static final String PUBLIC_KEY_END_KEY_STRING = "-----END PUBLIC KEY-----";
        public static final String EMPTY_STRING = "";
        public static final String NEW_CR_CHARACTER = "\r";
        private static final String ALGORITHM = "RSA";
        public static String secretMessage  = "Some random words in no particular order.";
        
        public static void main(String[] args) {
             String pub_Key="-----BEGIN PUBLIC KEY-----\r\n" + 
                "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA993qkLy6s+EL5SQ7vqmZ\r\n" + 
                "LBZEV0/tc7T5x8yRJwN0WmWy2TxOnxjFuLvO2b9ai3aEe7X5a6jzl5aE99RXbo86\r\n" + 
                "IB2PDH1dDN+W2IKfQViRyZE8hKRZnLH+QEbbRr3a\r\n" + 
                "x/EVAnC/cObCKgjNY4jp30sCAwEAAQxxxxxxxx==\r\n" + 
                "-----END PUBLIC KEY-----";
             pub_Key=pub_Key.replaceAll(NEW_LINE_CHARACTER, EMPTY_STRING)
                        .replaceAll(PUBLIC_KEY_START_KEY_STRING, EMPTY_STRING)
                        .replaceAll(PUBLIC_KEY_END_KEY_STRING, EMPTY_STRING)
                        .replaceAll(NEW_CR_CHARACTER, EMPTY_STRING);
            
            byte[] publicKey = Base64.getDecoder().decode(pub_Key.getBytes());
            try {
                byte[] encryptedData = encrypt(publicKey,
                        secretMessage.getBytes());
                
                String encryptedString = Base64.getEncoder().encodeToString(encryptedData);
                
                System.out.println("Output encryptedString: " + encryptedString);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        public static byte[] encrypt(byte[] publicKey, byte[] inputData)
                throws Exception {
    
            PublicKey key = KeyFactory.getInstance(ALGORITHM)
                    .generatePublic(new X509EncodedKeySpec(publicKey));
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
    
            byte[] encryptedBytes = cipher.doFinal(inputData);
    
            return encryptedBytes;
        }
    }

Output encryptedString:

Vu+8qX6X+pvLGteVdPjXjBEVaAvj0g1nposgzb/EBbFZOQnpIHXkXAg3DWvH/RGMDsFL/Ae+EsXzt56eqGEW4Xw2Z5M1igkGCngIXsBmmbutD/huacOORmOvDEgYs9+a0bZms2UWlrnNS7MnC6R+WD/6P4PdIOrxAaNVEvDwOWyDGNvQaL1uR/e1YXdCr8hItr2rj+Xy88jufcFcp0HtDcFdEfK4VwPp5aehAGqE/pwqvHOgfzthW2yXjap5BHLzqdnY3fKv8pcY8b5kSamRwBMfeyiorRMt6/HCGedi7rqjH3lNlUgOObtAfNbTCtLWOia1TafHRqDa5J5AkQ/s0TpExhNem534MbwT1OMXGGWU81MzAYsBACt1CY0/kkSH6NqGvI4ZuLjki8tyu+Vpz1l2cRTbwX26gNkk1Ah55P3ub/w+zGHFuDLtRT+No/SzR+9FD95oJOu/K8RTXVaiYfY2iWOyRplTXJ4i7wfWVgLvKMJJp9MRd5D5ru4Qsa+2KVf9COwhqatWPPeVF4qnfLmOF7Gf6RxMsBTi3u74b9BHH6AtCJGR/qh67yjN0MrLp7utskLDhR22ex6RdF+OuhV2OVeo7Ez3uTsNxJ1Y+Qyda3HaoVMO3d4SPL7Fnb/9eEWbf9gMR4xZ/JrKDssRC/TDLkaGS0cMMHZ+k6vCo+0=
Sign up to request clarification or add additional context in comments.

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.