Problem with encryption
Hello
I want to encrypt a message by using the public key which is stored on a file. I load the key from the file but i cannot initiate the cipher for the encryption. The key is encoded and stored on a file The code i use for loading the key is
FileInputStream PublicKey =new FileInputStream ("public.dat");
byte [] bPublicKey =newbyte [PublicKey.available()];
PublicKey.read (bPublicKey);
PublicKey.close ();
Thanks in advance for any help
So how did you write the bytes of the key and how are you trying to use the bytes of the key?
P.S. The method available() does not guarantee to return the length of the file and FileInputStream.read(bPublicKey) does not guarantee to read all the bytes of the file. Use File.length() and DataInputStream.readFully(bPublicKey).
Message was edited by:
sabre150
Sabre150 thank you for your reply.I must say that i am new in cryptography (this is my first program). I stored the generated public key with these lines of code
FileOutputStream pukey = new FileOutputStream(new File(
"public.dat"));
pukey.write(pub.getEncoded());
pukey.close();
Assuming that 'pub' is a PublicKey then that looks OK. How are you trying to turn the bytes back into a PublicKey and how are you trying to init the Cipher?
Pub is the Public Key. Im trying to init the cipher with Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, key);But i cannot initialise it because i dont know how to translate the bytes into public key.
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyAsBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
Thank you so much for your support. I think i will come back with new question though
Unfortunately the bytes are not decoded.I receive this error
java.security.spec.InvalidKeySpecException: Unknown key spec: Could not decode public key from BER.
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePublic(DashoA6275)
at java.security.KeyFactory.generatePublic(KeyFactory.java:221)
at senderpak.sender.main(sender.java:52)
You need to post your code for the key generation, encryption and decryption.
Here is the code.I first generate the pair of keys and i store them in two separate files.This is done in one application.
System.out.println( "\nStart generating RSA key" );
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
PrivateKey priv = key.getPrivate();
PublicKey pub = key.getPublic();
System.out.println( "Finish generating RSA key" );
FileOutputStream pukey = new FileOutputStream(new File("public.dat"));
pukey.write(pub.getEncoded());
pukey.close();
FileOutputStream prkeyFos = new FileOutputStream(new File("private.dat"));
prkeyFos.write(pub.getEncoded());
prkeyFos.close();
The second application must load the public key received from the first application and then encrypt a plaintext message.The code i have is
byte[] plainText = "This is a message".getBytes("UTF8");
FileOutputStream plainfile = new FileOutputStream("plaintext.txt");
plainfile.write(plainText);
plainfile.close();
DataInputStream dis = new DataInputStream(new FileInputStream("public.dat"));
byte[] pubKeyBytes = new byte[(int)"public.dat".length()];
dis.readFully(pubKeyBytes);
dis.close();
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pubKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(publicKeySpec);
By inserting the code you gave me (last 3 lines) i receive the error posted on previoud post.I appreciate your help.Thank you very much!!!!!!
Two points
1) Look very carefully at the code you used to write out the private key!
2) On reading the keys you need the file length not the length of the file name (File.length() not String.length()).
When I write code like this, I test to make sure that the bytes a I write and then read back are identical. That way I don't fall foul of the sort of error you have with using the wrong length() method.
> Two points
> 1) Look very carefully at the code you used to write
> out the private key!
By mistake i wrote the public key in the file for the private key.Correct?
> 2) On reading the keys you need the file length not
> the length of the file name (File.length() not
> String.length()).
i am ashame but i cannot resolve the second point.
File f = new File("key file name");int len = (int)f.length();.I think you need to spend some time with the IO tutorial.
I must say that i have to spend a lot of time with Java in general. I am in front of my computer about 10 hours.Maybe i need some rest but its imposible for me to sleep....
I dont have words to say how grateful i am to you Sabre. With that code it worked.
File f = new File("public.dat");
int len = (int)f.length();
DataInputStream dis = new DataInputStream(new FileInputStream(f));
byte[] pubKeyBytes = new byte[len];
dis.readFully(pubKeyBytes);
dis.close();
Hello again
I now have problems with decryption. I encrypted the plaintext with the use of the public key and i stored the encrypted text in a file.
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println( "\n" + cipher.getProvider().getInfo() );
// encrypt the plaintext using the public key
System.out.println( "\nStart encryption" );
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = cipher.doFinal(plainText);
FileOutputStream encrfile = new FileOutputStream("encrypt.txt");
encrfile.write(cipherText);
encrfile.close();
I tried to load the encrypted text from the file and by using the private key (which i loaded from a file as well), i could not descrypt the text. Do i have to decode first the text file?Here is the code.
File privatef = new File("private.dat");
int len = (int)privatef.length();
DataInputStream dis = new DataInputStream(new FileInputStream(privatef));
byte[] prKeyBytes = new byte[len];
dis.readFully(prKeyBytes);
dis.close();
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(prKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(priKeySpec);
File encryptf = new File("encrypt.txt");
int enclen = (int)encryptf.length();
DataInputStream dis2 = new DataInputStream(new FileInputStream(encryptf));
byte[] encrBytes = new byte[enclen];
dis2.readFully(encrBytes);
dis2.close();
// get an RSA cipher object and print the provider
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// decrypt the ciphertext using the private key
System.out.println( "\nStart decryption" );
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] newPlainText = cipher.doFinal(encrBytes);
System.out.println( "Finish decryption: " );
System.out.println( new String(newPlainText, "UTF8") );
The type of error i receive is avax.crypto.BadPaddingException: unknown block type
at org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA6275)
at receiverpak.receiver.main(receiver.java:94)
