13. december 2004 - 20:22Der er
10 kommentarer og 1 løsning
How to encrypt a file with only assym. crypto
Hello!
I'm working with a encryption project.
The task is to build a app that can encrypt a file like a jpg-file. When the encryption is done the application shall not be able to decrypt it back.
After this the encrypted file may be send over a network an decrypted by an other application.
My idea how to solve this would be like using assymetric keys like public and private keys.
And I my first attempt of doing this would be (please correct me if this is stupid in any way):
1 generate keys 2 put public key in app 1 3 put private key in app 2 4 encrypt a file with the public key in app 1 5 send the encrypted file by a regular email 6 encrypt the received file in app2 with the private key.
How ever when I run this approach like below I get a: javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes
it occurs at line with: byte[] encryptedFileBytes = cipher.doFinal(decryptedFileBytes);
//Save keys to files ObjectOutputStream objectOutputStream = new ObjectOutputStream( new FileOutputStream(new File("assignments6/image_filter_private_key")) ); objectOutputStream.writeObject(privateKey); objectOutputStream.flush(); objectOutputStream.close();
objectOutputStream = new ObjectOutputStream( new FileOutputStream(new File("assignments6/image_filter_public_key")) ); objectOutputStream.writeObject(publicKey); objectOutputStream.flush(); objectOutputStream.close();
//Get original text FileInputStream fileInputStream = new FileInputStream(file); byte[] decryptedFileBytes = new byte[fileInputStream.available()]; fileInputStream.read(decryptedFileBytes); fileInputStream.close();
//Get the key ObjectInputStream objectInputStream = new ObjectInputStream( new FileInputStream( new File("assignments6/image_filter_public_key") ) ); publicKey = (PublicKey)objectInputStream.readObject();
//Save encrypted data FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write(encryptedFileBytes); fileOutputStream.flush(); fileOutputStream.close(); } catch(Exception e) { e.printStackTrace(); } }
I really thought that this would be a correct approch to encrypt a file with public and private keys. If I'm right nobody then the holder of the private key should be able to decrypt it.
It is common practice to encrypt the main text with a randomly chossen symmetric key and the just use the assymmetric key to encrypt the symmetric key.
Do you by any chance got some code that do what you are sayin in your first comment, I'm not sure taht I understand. Should I devide my original data into smaller chunks? But how do I do that?
public class RSA { public static void main(String[] args) { String s2; try { String s = "ABC DEF GHIJ 123 - ÆØÅæøå - dette er en lang tekst - " + "som gerne skulle være længere end 177 tegn - bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla"; byte[] plain = s.getBytes("ISO-8859-1"); System.out.println(s); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] code = new byte[(((plain.length-1)/100+1))*128]; int ixplain = 0; int ixcode = 0; while((plain.length - ixplain) > 100) { ixcode += cipher.doFinal(plain, ixplain, 100, code, ixcode); ixplain += 100; } cipher.doFinal(plain, ixplain, plain.length - ixplain, code, ixcode); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] plain2 = new byte[code.length]; int ixplain2 = 0; int ixcode2 = 0; while((code.length - ixcode2) > 128) { ixplain2 += cipher.doFinal(code, ixcode2, 128, plain2, ixplain2); ixcode2 += 128; } ixplain2 += cipher.doFinal(code, ixcode2, code.length - ixcode2, plain2, ixplain2); s2 = new String(plain2, 0, ixplain2, "ISO-8859-1"); System.out.println(s2); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (ShortBufferException e) { e.printStackTrace(); } } }
My guess is that you must use 128 for chunks for the encrypted part. Or is it possible to use any other number?
I also guess that you can use any number under 118 for chunks for the decrypted part, that must be a limit in RSA?
Perhaps you could give a hint way this may be stupid and perhaps I can ask you how you would have solved this task in some small pseduo-code. The task: The task is to build a app that can encrypt a file like a jpg-file. When the encryption is done the application shall not be able to decrypt it back.
public class RSA3DES { public static void main(String[] args) { try { String s = "ABC DEF GHIJ 123 - ÆØÅæøå - dette er en lang tekst - " + "som gerne skulle være længere end 117 tegn - bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla " + "bla bla bla bla bla bla bla bla bla bla bla bla bla"; byte[] plain = s.getBytes("ISO-8859-1"); System.out.println(s); Random rng = new Random(); byte[] key = new byte[24]; rng.nextBytes(key); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey = secretKeyFactory.generateSecret(new DESedeKeySpec(key)); Cipher realcipher = Cipher.getInstance("DESede"); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); Cipher cipher = Cipher.getInstance("RSA"); realcipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] code = realcipher.doFinal(plain); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] codekey = cipher.doFinal(secretKey.getEncoded()); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] key2 = cipher.doFinal(codekey); realcipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key2, "DESede")); byte[] plain2 = realcipher.doFinal(code); String s2 = new String(plain2, "ISO-8859-1"); System.out.println(s2); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } } }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.