RSA implementations for Java, alternative to BC - java

The RSA implementation that ships with
Bouncy Castle only allows the
encrypting of a single block of data.
The RSA algorithm is not suited to
streaming data and should not be used
that way. In a situation like this you
should encrypt the data using a
randomly generated key and a symmetric
cipher, after that you should encrypt
the randomly generated key using RSA,
and then send the encrypted data and
the encrypted random key to the other
end where they can reverse the process
(ie. decrypt the random key using
their RSA private key and then decrypt
the data).
I can't use the workaround of using symmetric key. So, are there other implementations of RSA than Bouncy Castle?

This restriction isn't just something randomly invented by Bouncy Castle, and using a symmetric key isn't a "workaround": it's correct practice.
The RSA algorithm is intrinsically not suited to encrypting large quantities of data. If you really really really really really want to use it on a large quantity of data, then you could just about split your data up into blocks small enough, and encrypt each one. But this is not standard practice and you could run into security issues you haven't thought of, whereas block ciphers such as AES have standard means for dealing with the issues you may come across (look at block modes-- essentially there's a security issue for example encrypting the same data with the same key multiple times, and block modes are a built in way to deal with this).
I would really just stick to the standard practice of streaming with symmetric encryption and encrypting the symmetric key (and essentially nothing else) with RSA.

Yes, the JDK comes with one but it won't do you any good. Typically, this is the way encryption is done when using RSA. You generate a random symmetric key and encrypt your data with that. You encrypt the symmetric key with RSA and transmit.
If you want to encrypt only with RSA and leave out the symmetric part you can do that (with BC or without) but be warned that it's going to be awfully slow to encrypt or decrypt and take up a LOT more space than the typical alternative.

All RSA implementations would have a similar caveat. That's the nature of the RSA algorithm.
Using a symmetric key as described isn't a "workaround". It's "correct." If there's any possibility of applying a better encryption technique, it would be worth pursuing.

You can invoke RSA once for each data "block". Don't do this.
RSA isn't a block cipher. It accepts inputs in the range [0,p×q], not [0,2n−1]. In the obvious implementation, each output block is at least 1 bit larger than an input block, which is not ideal.
RSA is multiplicative. Using RSAe() to mean RSA encryption with key e,
RSAe(0) = 0
RSAe(1) = 1
RSAe(a*b) = RSAe(a) × RSAe(a)
Why can't you generate a symmetric key?

Related

In (FIPS PUB-197) AES-128 cipher, how many unique 128 bit cipher keys are required, if my plain-text is divided into N 128 bit blocks?

All descriptions of the AES-128 algorithm that I've found on the inter-web talk about inputting a 128 bit plaintext that undergoes 11 rounds of transformations to produce a 128 bit cipher text. My question is:
Since the actual message to be sent can occupy more than just a single 128 bit "block", do I need a unique key for each 128 bit block that I generate from my message to be encrypted using AES-128, or can I use the same key for each of those 128 bit blocks?
I need this information in regards to creating an algorithm for a paper (journal), so I need to be scientifically correct in my use of AES-128, which forms a part of my algorithm.
You may want to have a look at Block_cipher_mode_of_operation.
If you use the same key for every block, you are using the Electronic codebook (ECB). However this mode of operation is not recomended.
Something more secure would be the Galois/Counter mode or the Cipher block chaining mode. For more information read the wiki article.
I'm not familiar with FIPS PUB-197, but I know the security properties of AES.
AES is a block cipher and all block ciphers are modeled in such a way that you cannot deduce the key even if you know both ciphertext and plaintext. With this property, you can follow that using the same key for multiple blocks is perfectly secure even if parts of the plaintext and ciphertext are known to the attacker. This property emerges after cryptanalysis that is done by cryptographers when they want to find holes in an algorithm like AES.
Also, if you have 11 rounds for a 128 bit key, you don't have AES, but something else.

Overriding default Java AES round key method

I'm reverse engineering an interesting piece of javascript malware that uses AES 256 to encrypt/decrypt however it uses a custom implementation of aesjs that has no direct key input. Instead the key has already been expanded and the round keys have been hardcoded, how is this something I could replicate in java? I've looked into overwriting the aes encryption class but am struggling to find the relevant method.

BCrypt (blowfish) password for AES 256 (Rijndael) encrypted text

I decided to try BCrypt for hashing key for AES256 (Rijndael/CBC).
Problem is that AES256 key has to be 32 bytes long. BCrypt key is 60 bytes long and naturally always different. Maybe pretty hard and long week is to blame but I am not able to see how could I use a key hashed with BCrypt in combination with AES256. Am I just tired and blind or there is no way to do this?
Thanks
Are you trying to hash something (like a password) and use that as an AES Key?
I'm not familiar with BCrypt, but SHA-256 would create a hash that is the same size as an AES 256 key. Or if your bent on using BCrypt you could just read the first 32 bytes of that hash and discard the rest.
I don't think you should ever discard bytes from cryptography calculations, because those bytes are supposed to support the other bytes you kept - discarding some weakens the output.
What you need is a secure Key Derivation Function. Truncating the bytes as suggested in the comments works sometimes, but it always depends on the context, so don't do it if you're not absolutely sure about it.
Truncating won't work anyway in situations where you need to "stretch" your input, it's also where the most mistakes are made. If you can't create your key using a secure random generator, typically, what you want to do is transform some non-random input (e.g. password) into something worth as key material. Obviously, the entropy of non-random data is normally not good enough for the purpose.
Look into PKCS#5 and use its PBKDF2 if you want to transform passwords into arbitrary-length keys for AES or any other symmetric encryption algorithm.

Choosing a encryption key from Diffie-Hellman output

I implemented Diffie–Hellman key exchange in Java with some large groups from RFC 3526. My output is a fairly large array of bytes. Is it safe to use the first 448 bits (56 bytes) of the output for a blowfish key? Should I transform the bytes in any way, or pick any specific bytes for the key?
From a theoretical point of view, no, it is not safe. Not that I could pinpoint an actual attack; but the output of a Diffie-Hellman key exchange is an element of a group consisting in q elements and offering sqrt(q) security at most. Truncating parts of the encoding of that element does not look like a good idea...
The "proper" way is to use a one-way key derivation function. In simple words, process the Diffie-Hellman output with a good hash function such as SHA-256 and use the hash result as key. Hashing time will be negligible with regards to the Diffie-Hellman step. Java already includes fine implementations of SHA-256 and SHA-512, and if you are after compatibility with very old Java implementations (e.g. the Microsoft JVM which was coming with Internet Explorer 5.5) then you can use an independent Java implementation of SHA-2 such as the one in sphlib. Or possibly reimplement it from the spec (that's not hard): FIPS 180-3 (a PDF file).
If you need more than 128 bits for your key then this means that you are a time-traveler from year 2050 or so; 128 bits are (much) more than enough to protect you for the time being, assuming that you use a proper symmetric encryption scheme.
Speaking of which: Blowfish is not really recommended anymore. It has 64-bit blocks, which implies trouble when the encrypted data length reaches a few gigabytes, a size which is not that big nowadays. You would be better off using a 128-bit block cipher such as the AES. Also, in any serious symmetric encryption system you will need a keyed integrity check. This can be done with a MAC (Message Authentication Code) such as HMAC, itself built over a hash function (then again, easy to implement, and there is a Java implementation in sphlib). Or, even better, use the AES in a combined encryption/MAC mode which will handle the tricky details for you (because using a block cipher properly is not easy); lookup CWC and GCM (both are patent-free; the latter has been approved by NIST).
The solution that you propose depends on whether the most significant bits of a Diffie-Hellman exchange are hard core. There are some small results known that show that the most significant bits are unpredictable, but I'm not aware of a paper that is strong enough to show that your approach is correct.
However, there are several proposals for a key derivation from Diffie-Hellman keys.
E.g. a nice paper is NIST SP 800-135. So far this is only a draft and can be found here. However, it reviews some existing standards. Of course, using a standard is always preferable to develop it yourself.
While Thomas Pornin's proposal looks reasonable it is nonetheless an ad hoc solution. And to be on the safe side you should probably not use it. Rather I'd use something that has been analyzed (e.g. the key derivation scheme use in TLS version 1.2).

Java SealedObject

I am encrypting an string with PBEWITHSHA256AND128BITAES-CBC-BC using SealedObject and write it to a file. After encrypting when i do a cat on the resulting file i i get read the salt used and the algorithm used in plain text even though the actual data is encrypted.
Doesn't that give crackers a head start? They know the salt and the algorithm with basically zero effort.
The salt isn't secret. Its purpose is generally to prevent dictionary attacks.
Keeping the algorithm secret is security through obscurity, which is pretty much universally discouraged.
When you use PBE (Password-Based Encryption), salt and iteration are just to make cracking more expensive. You only need to generate key once but guessers will have to try millions.
If you require salt to be secret, it defeats the purpose of the password. Password is something easy to remember but less secure. If you really worried about security, don't use password. Use a secret key.
Hiding salt is practically a double key scheme. In most cases, it doesn't make your cipher much stronger.

Categories

Resources