I have some issues regarding BlowFish encryption. I'm developing a portlet in Java deployed under weblogic. I receive from an internet usb device a string encrypted with BlowFish - nCFB mode and i need to obtain the original string from it. I implemented blowfish decryption, but i don't know how can i decrypt using the nCFB mode. It's very few documentation on the internet but i was able to find a tool that does it at:
http://www.tools4noobs.com/online_tools/decrypt/
Giving my input string and password, it retrieves the result. But on java i can't do
Cipher cipher = Cipher.getInstance("Blowfish/NCFB/NoPadding");
Because the NCFB is not recognized. I did my implementation with
Cipher cipher = Cipher.getInstance("Blowfish/CFB/NoPadding");
But it only decodes the first 3 characters. How can i decrypt using the NCFB mode instead of CFB ?
I was able to found a little something about nCFB at http://mcrypt.hellug.gr/lib/mcrypt.3.html , but it belongs to mcrypt php library.
Is there a java API able to do this ? Or how can i get the CFB mode to work as NCFB ?
Best regards
CFB (Cypher Feed Back) mode feeds back part or all of the cyphertext when decrypting. the "n" in nCFB tells you how much to feed back. The default is the entire block. You will need to read the documentation to find out what value of n is being used to encrypt, and how to add that parameter to your decryption algorithm. Given that the first three characters are decrypting correctly, it might be that n is 24 bits, though I am not sure of that.
Normally CTR mode is less trouble than CFB.
Related
I have a requirement to encrypt with AES -symmetric- a string and then share the encrypted string with a client.
They know the key (we have communicated over the phone) and they should be able to decipher the encrypted string.
However the Java implementations I have found all require to share the salt (or IV) along with the encrypted document. This defeats the purpose of sharing only the cipher text and a symmetric key (before hand) if I somehow have to send the salt every time.
Am I understanding something wrong? Is there a way to share only the cipher text and the symmetric key?
The purpose of the IV in encryption is randomization. If you use ECB mode of operation, it can leak information about the ciphertexts that are encrypted under the same key. See the famous penguin in Wikipedia mode of operations.
E(k,m) = E(k,m') iff m=m'
The modern modes of operation use IV, as AES-GCM which is in TLS 1.3 cipher suites.
You should tell the big company about the danger. I'm pretty sure that they can easily adapt to your case very easily.
Note: ECB mode can only be safe, if
your data is always different (no pattern)
you generate a new key for every encryption with a key agreement protocol as Diffie-Hellman key exchange, and this is not your case.
Usually the IV is shared by appending it to the cipher text. So, eventually you are sending a single Base64 encoded string.
So, if you are worried about breaking a contract by sending two fields (one IV and one cipher text) instead of sending just one field, let me assure you that you're going to send a single field only. And the decryption logic knows how to extract the IV from the received string and use it in the decryption process.
Note that there are some key distinctions between IV and key:
Key is a secret, IV is not
Many messages can be encrypted with the same key, but IV is different for every new message. The key and IV combination has to be unique for every message and the IV also has to be random
Therefore, you do not share IV the same way as key. Since IV changes for every message, it is actually appended with the cipher text to form a single string which is then sent as the encrypted output. So, the decryption logic takes as input only the key and your encrypted output; it knows how to extract the IV and the cipher text from the encrypted output.
On today's date if anyone needs to encrypt something using AES, the usual choice is an authenticated encryption mode like GCM which provides not only confidentiality but also integrity in a secured way.
Unless the recipient (in your case) is rigidly specifying a particular mode for AES, the default choice would always be AES with GCM. And even if the recipient proposes some mode that is not an authenticated encryption mode, you may consider explaining to them the benefits of using authenticated encryption mode.
You'll find a complete java implementation with detailed explanation here.
You may also want to read this along with the comments to understand it better.
I am developing App for Android and IOS
For android I am using "AES/CBC/NoPadding" Cipher and for IOS am using CommonCrypto with same algo/mode/padding as Android
I am initializing the ciphers with common key, for getting same result in both platforms
In Android , am using cipher.update(inpBuf, inpOffset, inpLen, outBuf, outOffset) for encrypting/decryption purpose, same way I want to do it in IOS.
I Have tried CCCryptorUpdate in IOS , but the result array was [0,0,0......0]
Please guide me, where am gone wrong?
AES is a block cipher that encrypts data in chunks of 16 bytes. When calling update() all blocks of 16 bytes will be encrypted and any excessive bytes will wait around until the next update() call. When no more data needs encryption you finishes of the encryption with a doFinal() that flushes the last block + and applies any padding needed. Why are you using NoPadding? Are you ensuring you data matches the block size of AES yourself?
When decrypting in IOS you use the corosponding CCCryptorUpdate() and CCCryptorFinal(). Only after the CCCryptorFinal() you would have the full decrypted message. CCCryptorUpdate() might or might not return data, depending on how much is stuck in the buffer etc.
I'm decrypting some data using Java and Apache's most recent WSS4J library with 128-bit AES decryption.
I setup the the cipher which appears to be correct with the right padding, decryption algorithm, and cipher block mode.
I then make a call to doFinal() on the encrypted data bytes and it successfully returns a value.
My question is would it ever return a value that is only partially decrypted?
For example, let's say the first 16 bytes are still jumbled up after decryption, but the remainder of the data returned has been successfully decrypted, and is human-readable with the expected data there.
Would this mean that there could be an issue with my decryption process? Or would it not even be able to return a value from the doFinal() step if something was even slightly off with the decryption setup?
If I get a value returned from doFinal() would that mean that 100% the data returned is the original data before it was encrypted?
I'm decrypting data from a web service call and the owners of the web service are claiming that I must be doing something wrong during my decryption process and that they are sending the data correctly.
Yes, that is possible. A prime example would be if you try to decrypt something in CBC mode with the wrong Initialization Vector (IV). That would result in the first part decrypted to be invalid.
This is due to how the IV is XORed to the first block of plaintext in CBC mode.
I have a UI to add/edit password .These passwords are encrypted using Blowfish in CBC mode and it worked fine but during decryption it required a IV (it threw a parameter missing exception.)
I have used the cipher class while initiating the cipher so this would have taken care of the IV while encrypting.
So my doubt is,
should the IV be same for both encryption and decryption? I read on some pages that while decryption if we use an incorrect IV the first block will be incorrect but the remaining blocks would be correct .Can you explain on this?
IF the IV (in case of encryption and decryption using the same IV) be saved should it be saved as a plain object or encrypted along with the password using some delimiter ?Which will be safer?
Thanks in advance.
Yes, the IV should be the same for encryption/decryption. In CBC, if I recall properly, errors will cascade down the blocks. So the whole message will be wrong if you use the wrong IV.
The IV can be stored in plaintext. If you try and store it encrypted, you'll end up needing to store the IV used to encrypt the IV...
However, it is generally considered a bad practice to store passwords in an encrypted form. If someone were to retrieve you database, they'd only need to find one key to retrieve all the passwords.
The recommended way to store passwords is to use a hash function multiple times, also known as a PBKDF (password based key derivation function), either based on a plain hash or on a hmac function. See the OWASP password storage cheatsheet.
There are primitives for this in java, see the example on this page. (Search for Use a Password Hashing Algorithm and scroll down to the java implementation.)
I have an Android application that communicates with another java application. For the data encryption i use the javax.crypto library to encrypt and decrypt the data with a pre-shared key.
According to this question it's possible to get the source code from an APK file. So if somebody is able to read the source code of my application, he's also able to read/manipulate the encrypted data.
It's probably true, so is there a way to prevent this (additional measures, other security method)? Don't know if it have extra value but here is my encryption code:
private static String IV = "AAAAAAAAAAAAAAAA";
private static String ENCRYPTION_KEY = "0123456789abcdef";
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(ENCRYPTION_KEY.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(input.getBytes("UTF-8"));
EDIT:
Communication is send and recieving by NFC. My main issue is, if someone has the key he's able to read and write (abused) information to the other side (the NFC reader)
The pre-shared key is not safe!
For someone with just little java reverse engineering skills it is a job of five minutes to decompile your APK file and extracting the key. Once this has been done your crypto is effectively useless.
The standard approach to fix this is to use a key agreement algorithm. You can for example use the Diffie-Hellman key exchange to quickly and secure generate a common secret between two devices: Wikipedia on Diffie-Hellman
Build a hash from the generated common secret and use this as your AES encryption key for this session is a lot more secure and doesn't take much work.
If NFC is your transport layer you need bidirectional data exchanges for Diffie-Hellman to work. Therefore Android Beam will not be usable for you. You can however do bidirectinal data-transfer using host based card emulation on one phone and reader/writer mode on the other.
Using encryption when transmitting data over NFC is a good idea by the way, also the communication range is limited to some few centimeters, you can still sniff the communication from a few meters distance. NFC doesn't do any encryption for you.
A last word of warning: Cryptography is hard to do in practice. Before you send out anything of value over a cryptographic link please make sure that you have a good understanding of what you do. I recommend reading this book which is a good and practical introduction of cryptography: Bruce Schneider - Cryptography Engineering