Overriding default Java AES round key method - java

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.

Related

Java AES with de-hashing

I would like to ask if there is any possibility to do de-hashing with salt.
Because currently I using doing encrypt with salt and hash. But I want to study about de-hashing part, is it possible to do de-hashing ?
I'm assuming that by de-hashing, you mean reversing the hashing process.
Hashing is a form of one way encryption. The original message is entirely destroyed in the process of creating the hash and, therefore, it is not possible to reverse the process. If it is possible, then that is a problem with the hashing algorithm.
Or in more formal terms, Hashing algorithms, by definition, are not Bijective.

Creative/secure ways to protect data based on a shared secret in Java

I've been experimenting with some basic cryptography techniques in Java (my preferred programming language) and have a simple example that uses modular exponentiation to generate a shared secret between two client pairs.
But, given a shared secret, what are some simple-to-implement (yet secure) methods for actually using this secret to encrypt/decrypt or scramble/unscramble data being sent over the wire?
For example, if I have the String:
"So long, and thanks for all the fish"
And the shared secret (BigInteger):
1110278255331388386297296974141977
How can the String be sent over the wire in a way that allows for the clients to understand each other, while ensuring that without the shared secret, no middle man can interpret it?
I'm not asking for a finished implementation, just ideas or references to algorithms/techniques that can be used. I'm also avoiding relying on existing programs or APIs (like public/private keys) since this is just a side project for my own educational purposes.
There is a standard way of doing what you are after and that is called password-based key derivation. You need to use a secure symmetric encryption algorithm. You can of course go for asymmetric ones like RSA, but with a shared secret, that is redundant.
However, you don't want to use your shared secret directly.
Your shared secret may have an inappropriate size to be used as a key. For example, AES, as a good choice, accepts 128-bit and 256-bit keys and the shared secret may not be a good match.
The key for your symmetric algorithm of choice should be secure enough, which means that it should have a secure level of randomness which your shared secret may lack.
This is exactly the case algorithms like PBKDF2 (password-based key derivation function 2) are invented for. PBKDF2 is already implemented in standard java and you may use it. It generates a secure key with arbitrary size based on a "passphrase", which is simply the shared secret in this case. These family of algorithms have a iteration parameter, which indicates how many times a hash function is applied to derive the key. Make sure to set it to a high number like a few thousand.
I should note though that security (confidentiality and integrity of transmitted data) in this cases relies on your shared secret to be actually secret. I don't know how you are generating it, but you need to make sure that the process is secure. Diffie-Hellman Key Exchange is a good example. If you are not familiar with this, I recommend you to take a look and see what is does to ensure that the process is safe.
As it is already stated in the comments, you don't need to (and also should not) innovate in cryptography for a practical application. You will find anything you need already implemented and proven secure. Take my last sentence with a grain of salt though.

How to use Skipjack (skip32) in Java to randomize sequential integers from a database

Based on a previous question, I am using a sequential integer as a record ID in my database. I want to obfuscate the integer IDs using Skip32. I found a Java implementation but I am uncertain of how to initialize it using the standard JCE APIs. I need to encrypt an integer and decrypt it as necessary. Can anyone show me an example of this?
The code you found belongs to the Cryptix project. You need not just this one file, but you should take the whole package. Take the JCE package, install it as a provider. Then you should be able to use
Cipher c = Cipher.getInstance("SKIPJACK");
But actually, instead of using an unsupported library like Cryptix, using the BouncyCastle library (or parts thereof) might be more recommendable. They have lots of documentation, and a SkipJack-implementation, too.
I'm not sure why you would need to use Skipjack instead of any cipher which comes with your JRE, though - just for the smaller block size?
If I understand right, Skip32 is a separate cipher (working on 4-byte blocks), just build by similar principles like Skipjack (which works on 8-byte blocks). I didn't find any specification of it, only some C and Perl source code, so I doubt there will be some Java implementation available. Have a look at Format-preserving encryption on Wikipedia, or Can you create a strong blockcipher with small blocksize, given a strong blockcipher of conventional blocksize? on Cryptography Stack Exchange, which show other ways of building a small-block cipher from a larger one.
You might find this blog post on secure permutations with block ciphers useful in figuring out how to implement it. Any block cipher with a sufficiently short block size will suffice.

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).

RSA implementations for Java, alternative to BC

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?

Categories

Resources