• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

CipherOutputStream not outputing

 
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
I am trying to write to CipherOutputStream reading from file. It simply does not output any thing. But If I write only a string, its encrypted and outputted properly. Not sure what is going wrong.
Any help much appreciated.
Thanks
Aryan

 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok ....the issue is if the input is small around 60-100 bytes it works fine but else it does not.

CipherOutputStream has yet another issue you have to close the stream for it to fully flush...the flush wont do the job. But I have no issues with this as I can close but I need to pass lots of data.

Any ideas?

Thanks
Aryan
 
Ranch Hand
Posts: 220
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
RSA is a poor choice for encrypting large amounts of data and, in practice, is rarely used this way. In every standard I've seen, RSA is used to encrypt a symmetric crypto key which in turn encrypts the data. You're best bet is usually to find a higher-level library that implements one of these standards, like CMS or PGP for messages and TLS for online network traffic.

More particularly, Sun's RSA cipher implementation will only encrypt one block of data. I believe BouncyCastle's version will however encrypt multiple blocks, so you might try adding the BC provider and getting RSA from it with Cipher.getInstance("RSA/ECB/NOPADDING", "BC");
 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sun's RSA cipher implementation will only encrypt one block of data.



Can you please explain a bit more. Do you mean that it will encrypt/decrypt a block at a time but isn't that because of using ECB and not CBC or some other mode.

The issue is this application will be distributed to customers and they can encrypt certain files off line and send it to us. Using the corresponding private key we will decrypt these files. I don't think I can use a hybrid approach (RSA-AES).

Thanks
Aryan
 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok could not find a solution so I removed the CipherOutputStream and only used FileOutputStream after manually calling cipher.doFinal.

The only small issue I have is that when I decrypt the file, it is padded with
blank spaces.

If the last buffer read was 200 , it is padded with 56 white spaces as I am reading 256 bits at a time. I tried using cipher.doFinal(arr,0, numRead) both during encryption as well as decryption but still having the same issue.

Thanks
Aryan
 
greg stark
Ranch Hand
Posts: 220
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
With a normal block cipher like AES, Cipher.update() and Cipher.doFinal() will encrypt as many blocks as necessary to process all the input. But using RSA, only one block can be encrypted. A "block" in RSA is roughly the number of bytes in the modulus.

The application you mention is perfectly suited to the hybrid method. It is just an example of message encryption, so you ought to consider for example PGP. You could just use the stand-alone PGP executable. If you have some special requirements that force you to write code, you could use the cryptix or bouncycastle PGP libraries.

No matter whether you use CipherOutputStream or not, Sun's RSA cipher implementation will only encrypt one block.
 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry Greg but would appreciate if you could confirm or correct my understanding.

The key size for the RSA key is 2048 bits that I use which is 256 bytes.

The application reads 256 bits from the file and passes it to cipher.doFinal

Are you saying that if I pass more than 256 bytes to cipher.doFinal, Sun's RSA implementation will only process the first 256 because of the key size/modulus.

If I use a hybrid approach where & how do I keep my AES key? This application ll be distributed to customers. If I encrypt is using my private key and store it as part of the application, the application can be reverse engineered and encrypted key extracted. Customers have the public key and can decrypt it.

I am currently reading about Bouncy Castle PGP libraries. Will comment later

Thanks
Aryan
 
greg stark
Ranch Hand
Posts: 220
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Are you saying that if I pass more than 256 bytes to cipher.doFinal, Sun's RSA implementation will only process the first 256 because of the key size/modulus.



You can pass at most 256 bytes, sometimes not even that many. If you try to encrypt more an exception is thrown.

If I use a hybrid approach where & how do I keep my AES key? This application ll be distributed to customers. If I encrypt is using my private key and store it as part of the application, the application can be reverse engineered and encrypted key extracted. Customers have the public key and can decrypt it.



That doesn't make sense to me, but I guess I don't really understand what you are trying to do.
 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Greg,

More than 256 it give error "javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes" which is understandable.

Less than 256, it decrypts will but has lots of white spaces at the beginning and within text other places and the formating is lots. Not sure why?

Another try to explain the second part !!

What I meant is that this application is distributed over the Internet using Java web start.

Any one can download it. The application contains the public key certificate and there should be a AES key as well (AES key cannot be generate on the fly for example using DH. In short the only communication between the 2 parties is the file being sent). Where do I keep this AES file. Normally in hybrid approach the AES key is generate using DH or encrypted using server public key etc. In this case that is not the option. As there is no communication between server & client except the file, the AES key also has to be stored which makes the whole point of hybrid useless but at least the performance will be better. My question is how do I store this permanent AES key with the application.

Thanks
Aryan.
P.S. The key change will be enforced by changing the application, next time client access it, it ll be downloaded automatically using Java web start.
 
greg stark
Ranch Hand
Posts: 220
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The white space appears in part because you specified NOPADDING and in part due to the nature of RSA. NOPADDING is really something of a misnomer. It really means that the Cipher object is letting you take care of any padding. If you have a variable number of bytes that you are encrypting, you must have some way of retaining that information. Of course, PKCS1Padding will do that for you and more, at a modest cost of reducing the number of bytes available to you by 11.
 
Aryan Khan
Ranch Hand
Posts: 290
Oracle Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Greg ... tried with PKCS1Padding... Didn't work. Added BouncyCastle and just used "RSA" and no white spacing....

Any ways got it working....
Thanks
Aryan
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aryan Khan wrote:Greg ... tried with PKCS1Padding... Didn't work. Added BouncyCastle and just used "RSA" and no white spacing....

Any ways got it working....
Thanks
Aryan


Hi Aryan,

When you say you got it working, is that using RSA encryption on it's own or the hybrid method. I have tried the Bouncy Castle provider RSA and I find that the maximum block is still determined by the key size.

Any suggestions..

Thanks,

Hardev
 
Always look on the bright side of life. At least this ad is really tiny:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic