3

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.

6
  • 2
    You need an RSA PublicKey during init. Not a symmetric SecretKey. Commented Jun 8, 2012 at 23:05
  • How can I generate an RSAPublicKey with a byte[] key instead of BigInts? Commented Jun 8, 2012 at 23:14
  • Well you could pass a byte array into the constructor of BigInteger. But the fact that you're asking how to do so suggests you're doing something wrong. RSA keys, in order to be secure, can't just be formed out of any old string of bytes. They have to comply with certain conditions. That's why the call KeyPairGenerator.genKeyPair() is provided for you. Commented Jun 8, 2012 at 23:25
  • I don't know if this tutorial of mine on RSA encryption is of any help javamex.com/tutorials/cryptography/rsa_encryption.shtml Commented Jun 8, 2012 at 23:26
  • The byte[] array was created with a key generator and then used .getEncoded() on the keys to get them. So, the solution was just: PublicKey key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(byteKey)); Sorry for the hassle, hope this helps someone who makes the same mistake I did.. Commented Jun 8, 2012 at 23:38

1 Answer 1

7

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"
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.