Using RSA encryption in Java without BouncyCastle

encryption, java, rsa

Solution

As was said in the comments, `SecretKeySpec` is for symmetric algorithms only. You mentioned that you got your `byte[]` containing the key by calling `getEncoded`.

There are two possibilities and two resulting formats:

Encoding of an RSA PrivateKey

Calling `PrivateKey#getEncoded` on an instance of an RSA private key will result in a PKCS#8 encoding for private keys, and it can be restored with the help of PKCS8EncodedKeySpec.

Encoding of an RSA PublicKey

`PublicKey#getEncoded` on an RSA public key results in the generic X.509 public key encoding, and can be restored with X509EncodedKeySpec.

Example Usage

byte[] data = "test".getBytes("UTF8");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair keyPair = kpg.genKeyPair();
        
byte[] pk = keyPair.getPublic().getEncoded();
X509EncodedKeySpec spec = new X509EncodedKeySpec(pk);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(data);
        
byte[] priv = keyPair.getPrivate().getEncoded();
PKCS8EncodedKeySpec spec2 = new PKCS8EncodedKeySpec(priv);
PrivateKey privKey = keyFactory.generatePrivate(spec2);
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] plain = cipher.doFinal(encrypted);
        
System.out.println(new String(plain, "UTF8")); //=> "test"

Problem

In my program, I'm trying to encrypt some plaintext with RSA using the following code: ``` static String RSAEncrypt(String pubkey, String plain){ return encrypt(pubkey,plain,"RSA"); } static String encrypt(String stringKey, String plain, String algo){ String enc="failed"; try{ byte[] byteKey = new BASE64Decoder().decodeBuffer(stringKey); Key key = new SecretKeySpec(byteKey,algo); byte[] data = plain.getBytes(); Cipher c = Cipher.getInstance(algo); c.init(Cipher.ENCRYPT_MODE, key); byte[] encVal = c.doFinal(data); enc = new BASE64Encoder().encode(encVal); }catch(Exception e){e.printStackTrace();} return enc; } ``` However, when it runs, it shows the following error: ``` java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec at javax.crypto.Cipher.chooseProvider(Cipher.java:877) at javax.crypto.Cipher.init(Cipher.java:1212) at javax.crypto.Cipher.init(Cipher.java:1152) at Crypto.encrypt(Crypto.java:37) at Crypto.RSAEncrypt(Crypto.java:62) ``` I have tried changing it to RSA/None/PKCS1Padding and RSA/ECB/PKCS1Padding to no avail.. I know that installing BouncyCastle may help but I'd like to avoid it (I'd like to avoid more dependencies and I've been having some issues installing it anyway). Thanks in advance for any ideas.

Original source