使用 RSA 算法使用 public 密钥加密字符串 - Java 中的无效密钥格式异常

To encrypt string with public key using RSA algorithm - invalid key format exception in Java

我正在尝试使用 RSA 加密字符串,并在 public 中键入 java。面临 "java.security.InvalidKeyException: invalid key format"

这样的异常

部分Public键:

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

注意:public 密钥生成并从客户端获取。

代码:

    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;
        }
    }

遇到如下异常。

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

我可以知道实现这个用例的方法吗(使用带有 public 密钥的 RSA 加密字符串)?

根据上面的建议,我尝试删除 \r 并对 public 密钥字符串执行 base64 解码,获取加密值。

工作代码:

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;
        }
    }

输出加密字符串:

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=