Decrypt Blowfish in Java (Generating a secret key in program) - java

My professor gave us a decryption assignment in which we were given a list of "encrypted" phrases and told to decrypt them. One of them is in blowfish. Me and one of my classmates have tried all the possible keys that he might use. Thus I was going to make a program in Java that would go through all possible keys decrypt the string and then write the decrypted message out to a file. Only problem is all the online tutorials that i can find on writing blowfish in Java have this interface SecretKey being read in from a file.
My question is how do you generate a SecretKey in a program?

This might help you:
byte[] key = getKey();
Cipher cipher = Cipher.getInstance("Blowfish");
SecretKeySpec keySpec = new SecretKeySpec(key, "Blowfish");
cipher.init(Cipher.DECRYPT_MODE, keySpec);

Here's the API you want to use. http://download.oracle.com/javase/6/docs/api/javax/crypto/spec/SecretKeySpec.html#SecretKeySpec%28byte%5b%5d,%20java.lang.String%29

Use a SecretKeySpec to generate a SecretKey using SecretKeyFactory.generate().

Related

Can KeyGenerator with SecureRandom("SHA1PRNG") be implemented in .Net Framework?

I'm hitting a brick wall, I hope someone can help. I have to encrypt a string that will be decrypted somewhere else (not under my control), as part of an authentication mechanism.
I'm told it uses a cipher "AES/ECB/PKCS5Padding", and I was given a 128 bit encryption key.
After implementing this in C#, it doesn't match the expected output.
While poking around a .jar I got my hands on, it seems that the encryption key is used in a different way than I was expecting, and I haven't figured out how, or even if it can, be ported to C#. Java:
String secretKey = "1234567890abcdef" //example
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom sRandom = SecureRandom.getInstance("SHA1PRNG");
sRandom.setSeed(secretKey.getBytes("UTF-8"));
keyGen.init(128, sRandom);
SecretKey generatedKey = keyGen.generateKey();
byte[] encodedKey = generatedKey.getEncoded();
SecretKeySpec realKey = new SecretKeySpec(encodedKey, "AES");
Cipher cipherInstance = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipherInstance.init(1, realKey);
String encryptedText bytesToHexString(cipherInstance.doFinal("text to encode".getBytes("UTF-8")));
I think I've got it all down except generating the encodedKey above.
Can someone shed some light please? :)
EDIT: The example above should produce 4a031f9da16717d442c0d06c415435b5 I believe.

Port Java AES ECB encryption into UWP compatible C# Code

I am very new in the field of cryptography and have been stuck on this problem for two days.
I have a java code for AES/ECB encryption and I want my uwp app to use the same encryption technique but whatever I've tried so far gives different encryption results.
There are many answers on stackoverflow suggesting to use RijndaelManaged class, but this class is not available for UWP.
Here's java snippet
public string encrypt(String input, string key) {
SecretKeySpec skey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes("UTF-8"));
return Base64.encodeToString(crypted,Base64.NO_WRAP);
}
You need to use this answer to see how to encrypt/decrypt. However, you need a different (ECB so insecure) algorithm. So instead of the given CBC cipher mode you need to use AesEcbPkcs7 from the SymmetricAlgorithmNames.
Notes:
PKCS#7 is the same as PKCS#5 as used in the Java code, more info here;
you of course don't need to use an IV for ECB mode, so strip that out;
the UTF-8 encoding and base 64 decoding I'll leave out, it should be easy to do these encodings in any language/environment (the Convert and UTF8Encoding classes seem to be available for UWP apps).

PHP crypt(pass, salt) alternative in Java - Blowfish algorithm

I'm using on php server function crypt like this:
$hash = crypt($password, '$2y$10$' . $salt);
It makes hash of password by Blowfish method.
I'm looking for java equivalent for crypt password.
I found this code, but I don't know where add $salt. More above:
String key = "abcd";
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(cipher.ENCRYPT_MODE, keySpec);
return DatatypeConverter.printBase64Binary(cipher.doFinal(key.getBytes()));
Thank's for every idea or answer.
Not an answer to your question but maybe it helps:
There is the Apache Commons Codec library that contains a Linux crypt(3) compatible function for at least des,md5,sha256 and sha512 based crypt() algorithms in case you don't really need blowfish but just something stronger than the traditional DES based hashes (use sha512 then):
http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java?view=markup
And there's other source code that implements the Blowfish algorithm but it's in C:
http://doxygen.postgresql.org/crypt-blowfish_8c_source.html
As you can see crypt() uses algorithms that are only based on those encryption ciphers but pipes the input several thousant times through them to get a nice hash value.
Now I did found some java implementations of crypt(3) with blowfish:
http://www.mindrot.org/projects/jBCrypt/ (last update 2010)
and
http://docs.spring.io/spring-security/site/docs/3.2.3.RELEASE/apidocs/org/springframework/security/crypto/bcrypt/BCrypt.html

Creating 8 byte IV in Java

Im new to cryptography in Java and I am trying to write a program to encrypt and decrypt a phrase using DES symmetric cipher, based on CBC mode of operation.
Can anyone tell me how to go about creating an 8-byte initialization vector and how to cast the new IV into AlgorithmParameterSpec class?
Also, which packages should I import?
Edit: Right now I have these lines:SecureRandom sr = new SecureRandom(); //create new secure random
byte [] iv = new byte[8]; //create an array of 8 bytes
sr.nextBytes(iv); //create random bytes to be used for the IV (?) Not too sure.
IvParameterSpec IV = new IvParameterSpec(iv); //creating the IV
Is my above approach correct?
Thanks.
Yes. Till Now You are right.
the Class IvParameterSpec is used to pass Initial Vector to Class Cipher
After this create a Cipher as below
Cipher cipherInstance = Cipher.getInstance("DES/CBC/NoPadding");
here DES/CBC/NoPadding is used because you are useing DES encryption in CBC mode.
Next is initializing it.
cipherInstance.init(Cipher.DECRYPT_MODE, Key, ivParameterSpec);
Parameters are:
1st is mode of encryption either Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
2nd is Secret Key You have generated using Class SecretKey
3rd is generated ivParameterSpec
and last line is
outData = cipherInstance.doFinal(input);
if mode is Decrypt it will return decrypted data and if mode is Encrypt it will return encrypted data.
Last but important catch all the Exceptions properly.
And you are done

Explanation to understand AES encryption code

I am creating a project to encrypt and decrypt a file. I have these two algorithms that work fine:
public static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static byte[] getRaw(String password_) throws Exception {
byte[] keyStart = password_.getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(keyStart);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
return key;
}
Now I need to explain how it works. Does it use a private key? Where is the key storage? Can anyone help me?
Note: see owlstead's answer for an excellent description of the flaws in your code example
Your encrypt() and decrypt() operations are performing AES encryption and decryption respectively, using Java's JCE libraries. A JCE provider will be selected to perform the actual cryptography - the provider chosen will be the first in the list of providers that offers an implementation of AES. You have defined the algorithm as only "AES", so the mode of operation and padding will be chosen by the provider. If you want to control this, use the form "AES/mode/padding" (see the docs for valid choices)
The getRaw method derives an AES key from a password. The raw bytes of the password provide the seed for a random number generator. The random number generator is then used to generate sufficient key material for a 128-bit AES key. A different password will produce a different seed, which should produce a different stream of random bytes and thus a different key. I suspect this approach is weakened by the lack of entropy present in most people's passwords, leading to a reduced key space and easier attacks.
There is no key storage in your example code. JCE keys are normally persisted using a KeyStore object and the storage mechanism is provider-dependent.
The above piece of code is a bunch of crap. Unfortunately it is frequently used as a code snippet for Android related code (Android code uses the same API as Java, so there is no need for an Android specific example, andt unfortunately it specifically fails on Android).
I'll explain the issues:
Using a SecureRandom as Password Based Key Derivation Function (PBKDF) is completely idiotic. The underlying implementation of the SecureRandom implementation may change. Furthermore, it is not specified by the SecureRandom that calling setSeed() as the first method will replace the seed; it may actually add the seed to the current state - and this is what certain newer android versions do.
Cipher.getInstance("AES") actually uses the provider defaults instead of specifying the mode of operation and padding mode for the given cipher. By default the Sun provider will use ECB mode which is not suitable for encrypting most data.
String.getBytes() - which is used for the password - returns the platform default encoding. Different platforms may have different default encodings. This means that different platforms will generate different keys.
Above code does not add a message authentication code (MAC or HMAC). This may lead to an attacker changing random ciphertext blocks, which leads to random plain text blocks. This may lead to loss of confidentiality as well if padding Oracle attacks apply.
It seems to me that you are a beginner in cryptography. Please use a higher level standard such as RNCryptor compatible code, or use a standard such as Cryptographic Message Syntax (CMS).

Categories

Resources