AES256 vs 3DES 256 key detection - java

How would I be able to determine the encryption of a key (AES256 or 3DES 256)...Since both keys will be 32 characters (8 bits per char * 32 char)=256 bits and Mime encoded.
Example
MQAyAEgAOgA5ADUAMwA3AD8AQgBFAD4A --->AES256 key
g1EOWGFb+JjCZ7BbH2RergtKUtDfXrNb --->3DES key
The AES keys were made in Openssl while the 3DES ones were made using Java with the following Apis.
javax.crypto.Cipher;
javax.crypto.KeyGenerator;
javax.crypto.SecretKey;
javax.crypto.SecretKeyFactory;
javax.crypto.spec.DESedeKeySpec;
javax.crypto.spec.IvParameterSpec;

First of all, there is no such thing as 3DES 256. 3DES has a key size of 128 or 192 bits, of which 112 and 168 bits are effectively used. Note that the security margin of 3DES is even lower.
AES on the other hand can be used with 128, 192 and 256 bits, all of which are used.
Now base 64 (not SMIME, that's a higher level protocol) has 6 bits per character (not excluding spurious bits at the end). If I check your keys both of them are 192 bit in size, so that won't help you distinguish the keys. You can use the Apache Codec library to decode base 64 strings.
However, your 3DES key - the second one - seems to use odd parity bytes for the 3 single DES keys. That can be used to distinguish the keys from each other. Note that this is not foolproof, a randomly generated AES key may have the parity bits set correctly by chance alone. However, the chance of that happening is somewhere around the order of 2^24.
It is possible to use the method DESedeKeySpec.isParityAdjusted(byte[] key, int offset) to check if the parity is correctly set. It is required to decode the base 64 string first of course.
Note that sometimes 3DES keys are distributed without having the parity set correctly. In your case, you need to use the KeyFactory to generate the keys otherwise the parity may not be set.
Another way of checking if the key is of the correct type is to decrypt some known plaintext/ciphertext/secretkey pair using both algorithms.

Related

Can I use 4096 bits as key length for java RSA with OAEP padding?

Im using RSA to encrypt an AES key and some other information. To not be vulnerable to the padding-oracle-attack I instantiate my Cipher the following way:
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
Now in the Oracle documentation (I'm using oracle-java) there are key lengths given: https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html
for RSA/ECB/OAEPWithSHA-256AndMGF1Padding it states 1024 and 2048 bits. Does that mean I cannot or should not use this cipher with a key length of 4096? Here's how I generated my key:
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
keygen.initialize(4096, SecureRandom.getInstanceStrong());
KeyPair keyPair = keygen.genKeyPair();
Can I use this key with RSA/ECB/OAEPWithSHA-256AndMGF1Padding?
Yes, you can use it with that key size and most Java providers - including those delivered by default for most runtimes - will be able to handle it.
The two key sizes - of which 1024 should not be used anymore and 2048 is considered rather small - just need to be supported by the default providers delivered by any official Java runtime. However software implementations can generally handle key sizes up to 16Ki bits (that's 16 times 1024 or 16 kibibit, in case you're unfamiliar with the term).
RSA / OAEP has been specified for use with any key size. However, most implementations require that the bit size is a multiple of 8 (to simplify bit / byte conversions), some require 32 bit increments (to simplify implementation using 32 bit integers) and some even require you to use key sizes of the form n = 2^x or n = 2^x + 2^(x-1). Some kind of minimum is obviously required to support the padding scheme as well, so 512 is commonly a lower bound. Some implementations got overly-protective and disallow key sizes smaller than (and sometimes including) 1024 bit.
So as your key is of form 2^x (with x = 12 of course) it is perfectly possible to use it, and the key size is extremely unlikely not to be supported. The unlimited cryptography extensions are not needed for (up to date?) 1.7 versions either, so you don't need to worry about that.
Some hardware modules have severe restrictions on the key size. Smart cards for instance can barely manage 4096 bit keys if they can manage them at all.
For those kind of uses you may want to consider using Elliptic Curve Cryptography instead. In this case you'd require encryption so ECIES which relies on ECDH using Certicom secp256r1 also known as NIST P-256 would be a viable and more secure alternative (until quantum computing becomes of age, in which case you would be screwed faster than with the RSA alternative).

Java AES 128 with 256 character key size

Is it possible to encrypt a file in Java with AES algorithm of Block size 128 bits and key size 256 characters(bytes) ?
As per references
the key size can be of maximum 256 bits or 32 characters.
I have a requirement to do with 256 characters, is it possible ?
AES has one block size of 128-bits and three key sizes of 128, 192 & 256 bits.
If you have a 256 characters, characters depending on the encoding can be more than 1 byte, you can use a key derivation method such as PBKDF2 (Password Based Key Derivation Function 2) to derive a key from the characters.
See the comment to the question.

How to generate custom length hash key?

I am trying to generate hash key using SHA-256 which is producing 64 length String but i need key of size<=32, what is the best algorithm recommended maintaining uniqueness? Please advice.
As already indicated you loose collision resistance for each bit you drop. Hashes however are considered to be indistinguishable from random. Because of the avalanche effect, each bit of the input is "represented" by each of the bits in the hash. So you can indeed simply use the first 128 bits / 16 bytes of the output of the hash. That would still leave you with some 64 bit of collision resistance. The more or less standard way to do this is to take the leftmost bytes.
Additional hints:
To have some additional security, use the result of a HMAC with a static, randomly generated 128 bit key instead of the output of a hash;
Of course you could also encode the hash in base 64 and use that, if you can store any string instead of only hexadecimals. In that case you can fit 32 * 6 = 192 bits into the value, which would result in higher security than a SHA-1 hash (which is considered insecure nowadays, keep to SHA-2).

Generate AES key with a given length which contains a-Z0-9

is it possible to create a secret key using AES but with a given length and it should cointain only 0-9a-Z?
I just need a 32 characters key as a SecretKey spec :( for AES256 encryption/deceryption
is it possible to create a secret key using AES but with a given length and it should cointain only 0-9a-Z?
It is. By generating an AES secret key value, and then making sure that the ascii value of each character is within the bounds of 0-8 (48 - 57) or a-z (97-122).. Where it isn't, simply ammend the value to be within the range.
But..
This would make a wildly unsafe key. By limiting your values so heavily, you are effectively limiting the amount of possible combinations. Whereas normally, it is 2^256 possible combinations (considered secure at this point), you're dimishing that to much less possible combinations... which isn't secure.
Also, the above algorithm I suggested would make an awful lot of repeating values. You'd be comparing differences, and then ammending until that difference is 0.. which means:
For any value < the desired value.
round value to desired value.
Let desired value = 100;
Let any value = 50;
50 --> 100;
Let any value = 60;
60 --> 100;
And ontop of that..
A Brute Force Attack will usually start out by testing aaaa... x 256. Then (aaaa x 255) 1. What I mean is, a brute force usually starts with alpha numeric characters. You're just making your key ripe for a cracking there.
AND ONTOP OF THAT..
An AES key is defined as 128, 192 or 256 bits. That is the standard. You can't change the length. What you can do is look into the Rijndael, which is what AES was before it became the standard. This can accept a wider range of key values.
AND ONTOP OF THAT
An AES key is generated by the key schedule, the way it is for a reason. It is designed to be cryptographically resistant to cryptanalysis. By messing with that, you compromise the security of the entire algorithm, thus making it pretty pointless implementing the cryptographic standard, when you're going to mess with the output.
I CANT FIND A BIGGER FONT
You want your output to be 32 characters long. In ASCII, that means 8 bits per character. Or 32 x 8 = 256. Well.. AES's recommended mode is 256 bits, so you're in luck. You can use a hashing algorithm which will generate values that should be within the bounds of a-z0-9.
A AES-256 key is 256 bit long, and would be too big to store in 32 characters (0-9a-Z).
However, if you relax your requirements a bit by extending your character set with 2 more characters (to 64 in total) - then you can store 6 bits of the key in one character - which then allows you to store a 192 bit AES key in the 32 characters.
Below code would create a 32 character base64 encoded string (0-9a-Z+/) of a 192 bit AES key:
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(192);
SecretKey key = keyGen.generateKey();
String keyBase64 = Base64.encode(key.getEncoded());

continued encryption with diffie-hellman shared key

I'm currently working on a protocol, which uses Diffie-Hellman for an key exchange.
I receive a packet, which consists of an aes-128 encrypted part and a 128 Bit DH Public Key.
In a very last step in the protocol, the aes key is sent to another peer in the network.
This aes-key should be encrypted with a cipher using a 128 bit strong secretkey.
I plan to use Blowfish (can also be another cipher, doesn't really matter for the problem)
Now to encrypt the aes-key, with lets say blowfish, I have to build a secretkey for the encryption with a class called SecretKeySpec (I'm using javax.crypto stuff), which takes an byteArray in the constructor to build the secretKey.
The sharedkey from DH is a 128 Bit BigInteger.
Well, now I can interpret my shared-key as a byteArray (wich gives me still 128 Bit in 16Bytes [where the numbers are interpreted as frames of 8 Bit data])
So my question is, how strong is my key really?
Is there any impact because I only use numbers as input for the byteArray (so does this limit the keyspace in any way?)
I think this is not the case, but I'm not 100% sure.
Maybe someone can do the math and proof me right or wrong.
If I'm wrong what keysize for the shared key give me piece of mind to finally get to the 128Bit SecretKey for the encryption?
The Crypto++ website suggests using a minimum p of 3072 bits (or 256 bits for an ECC implementation) to transport a 128 bit AES key.
You might wish to study the references provided at http://www.keylength.com/en/compare/ for further information about comparing key lengths among different algorithms.
Not an expert in DH here, but to me it seems that DH's keyspace for the shared key represented in n bits is somewhat smaller than 2^n.

Categories

Resources