I'm looking for a Java sample how to do RSA Encryption with a given public key (I have it in base64 format, seems it is 1024 bit length).
Below is my code, but I have InvalidKeySpec exception.
String publicKey = "AJOnAeTfeU4K+do5QdBM2BQUhfrRI2rYf/Gk4a3jZJB2ewekgq2VgLNislBdql/glA39w0NjXZyTg0mW917JdUlHqKoQ9765pJc4aTjvX+3IxdFhteyO2jE3vKX1GgA3i3n6+sMBAJiT3ax57i68mbT+KAeP1AX9199aj2W4JZeP";
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] res = new Base64Encoder().decode(publicKey.getBytes());
X509EncodedKeySpec KeySpec = new X509EncodedKeySpec(res);
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(KeySpec);
// here the exception occurs..
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(input.getBytes());
return cipherData;
Please give me the sample,
Your "key" is not a valid public key. It is a Base64 string which, when decoded, yields a sequence of 129 bytes, the first being 0x00, followed by 0x93. This is not a valid format for a RSA public key, but it suspiciously looks like the big-endian signed encoding of a 1024-bit integer (i.e. the kind of encoding returned by
BigInteger.toByteArray()
and used in ASN.1 "INTEGER" values). A RSA public key nominally consists of two integers, one being the modulus and the other the public exponent. A typical RSA modulus has length 1024 bits, so chances are that you have here the modulus. You still need the public exponent to complete the key.X509EncodedKeySpec
expects the DER encoding of an ASN.1 structure which identifies the algorithm as being RSA, and contains a nested encoded structure which itself contains the two integers for the RSA public key. Assembling such a structure by hand could prove difficult (it is doable, but requires some in-depth understanding of ASN.1). A simpler method would be to useRSAPublicKeySpec
:In the above, "
pubExp
" should be aBigInteger
containing the public exponent, which you do not give. 3 and 65537 are the traditional values for the public exponent, but others are possible, and you do not give enough information to discriminate between public exponents (i.e. your code will appear to work even if you do not use the right one). Basically, you only have half of the public key; you should ask whoever gave you that half to send you the other half as well.Note:
String.getBytes()
uses the platform default encoding, which is not always the same. If you insist on converting a string to a sequence of bytes, you should use an explicit charset name, such as"UTF-8"
, otherwise you may run into trouble if your code ever runs on, say, a Russian or Chinese system. Also, I do not know from where yourBase64Encoder
class comes from (it is not part of standard Java API) but chances are that it could also work directly over aString
, or aStringReader
, making the conversion step unnecessary.Your public key does not look like a Base64 encoded 1024 bit value. A 1024 bit value would require 172 characters (the last one being a filler
=
) and here we have 175 chars.For a test, replace the last four characters in your String with a single
=
and test if this eliminates the exception. This won't solve the problem but may point in correct direction.Here's how I manage to encrypt a string with only a RSA public key.
First save the public key in PEM-format to the filename pubkey.pem
Find the public RSA key modulus
Find the public RSA key Exponent
Then insert them into the following code.
Is your public key really X509 encoded? If not, then a unencoded Keyspec should help.