I inherited a Java (Spring) project in its maintenance phase, that just went through Veracode for the first time, and the only High flaw we have remaining is one reporting a "weak or broken" encryption algorithm. I'd prefer to spend the time learning more about cryptography, but this project is live in the wild so I need to start with a more immediate solution to get this application secured.
Here is the line Veracode is reporting specifically:
Cipher cipher = Cipher.getInstance("PBEWITHSHA1ANDDESEDE");
Veracode offers no information on:
Why this algorithm is broken/weak
Which algorithms might make for sufficient substitutes
Any other concerns to be aware of when selecting an appropriate algorithm
What could I replace "PBEWITHSHA1ANDDESEDE" with? Would that necessitate other refactors, or is it as simple as a string literal swap? I'd love to give more specification to help us narrow down which encryption algorithm would be best, but since Veracode isn't providing any, the only specification is, "encryption algorithm that satisfies Veracode."
Why this algorithm is broken/weak
It is mainly broken because it uses PBKDF1 instead of PBKDF2 (or another/better Password Based Key Derivation Function). Using triple DES is also a small weakness as it may only offer about 80 bits of security in certain settings. SHA-1 is broken and it may well be a reason why Veracrypt mentions "weak or broken" encryption algorithms, but actually the use of SHA-1 in a key derivation function is considered secure.
Which algorithms might make for sufficient substitutes
If you want to rely on build in functionality then PBEWithHmacSHA256AndAES_128 would be a direct replacement. Other schemes could include other derivation functions such as bcrypt, scrypt or Argon2 and other modes of encryption such as AES-GCM.
Any other concerns to be aware of when selecting an appropriate algorithm.
CBC as used in above schemes is not secure for transport mode security unless a MAC (message authentication) is added; it is only secure for in-place encryption where padding oracle attacks don't apply. This is also the case for your current scheme though.
Your scheme still relies on password security, which can be very weak in itself. Generally you want to use a high iteration count / work factor and / or make very sure that the password / pass phrase has sufficient strength.
No PBE scheme (including the one you are already using) is an implementation requirement for Java compatible JRE's. Although alternate JRE's probably will provide an implementation I would not count on it being present or correctly implemented in Java versions of other suppliers.
Related
I've been struggling with a simple problem for hours now. I am working on a desktop application (a wallet) which needs a seed phrase to operate.
Naturally, the seed needs to be encrypted with a password and stored into a config file. I've found Jasypt which enables me to encrypt a String easily but apparently Jaspyt's PBEStringencryptor is supposed to be unsafe/deprecated. Since there's only one password, salting it wouldn't make any sense (would it?).
I've found many other methods on stackoverflock but I keep saying experts showing up and claiming how unsecure method x is.
To sum up my question: since I am only dealing with a single seed phrase, would using Jasypt's Stringencryptor be sufficient or should I use a different method?
The reason you are struggling to find a secure solution is probably that there is no secure solution that works in general.
Let me restate the problem that I think you are trying to solve:
Your application needs a "secret" to operate.
You cannot trust the user. (If you could, then you could in theory get the user to supply the secret each time they use the system.)
You cannot rely on operating system access control to keep the "secret" safe, because of one or more of the following:
the operating system is inadequate or buggy
you don't trust the operators / administrators
you can't be sure that the system hasn't been hacked, or
the system is not physically secured. (If someone can get undetected physical access to the hardware for long enough, they can circumvent OS security.)
Given the above assumptions, there is no secure solution. No matter what your application code does, it is possible for someone with sufficient OS-level privilege (assigned properly, or acquired nefariously) to watch what your code is doing and intercept the secret.
So what is the solution?
If you can assume that the platform is secure and the operators are trusted, there are technical ways to keep the secret secure ... from a non-privileged user.
There are mitigations for some kinds of security attacks. For example, you could use a Hardware Security Module to hold the secret so that it doesn't need to be stored in the file system.
Otherwise ... run the software on your (secure) infrastructure rather than the user's PC or your customer's servers.
seed needs to be encrypted with a password and stored into a config file..
Seems you are correct, the most reasonable way to encrypt the seed would be using some sort of password based encryption (PBE..).
Since there's only one password, salting it wouldn't make any sense (would it?).
you are storing the encrypted seed value itself, so in this case you may be ok with some application-wide static salt
PBEStringencryptor is supposed to be unsafe/deprecated.
would using Jasypt's Stringencryptor be sufficient
I am not aware of Jasyp being unsecure, it depends more on used parameters (any reference?). I usually use pure Java with standard PBKDF2 a few examples. However, Jasyp makes encryption done properly without deeper knowledge. The problem with cryptography is that it's easy to completely break security just using wrong set of parameters or using it wrong way. If you are just starting, using PBEStringencryptor may be safer option.
Someone mentioned using a hardware module (e. g. smartcard, TPM,.. ), could be safer, but less portable
I'am not an Java developer but as per described, what I would do in your case is to use asymmetric encryption of your seed with the desired password before storing it into a config file.
You could use Rivest Shamir Adleman (RSA), Elliptic Curve Cryptography (ECC) to name a few algorithms.
Cheers
This may be a noobie question but I'm confused on how providers work. I've tried reading this https://docs.oracle.com/javase/7/docs/technotes/guides/security/overview/jsoverview.html but it doesn't quite make sense to me. Say we have:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC")
and
Cipher cipher= Cipher.getInstance("AES/CBC/PKCS5Padding")
According to the link it sounds like the provider indicates the implementation that is in use but isn't AES/CBC/PKCS5Padding basically the same independent of the provider? In the example does bouncy castle (what I'm guessing "BC" corresponds to) happen to have a more efficient algorithm than the default implementation? Thank you for your time.
isn't AES/CBC/PKCS5Padding basically the same independent of the
provider?
Yes, it is.
In the example does bouncy castle (what I'm guessing "BC" corresponds
to) happen to have a more efficient algorithm than the default
implementation?
Probably not. In the case of AES in particular, recent Oracle providers are likely to be dramatically faster than Bouncycastle due to their use of native AES hardware when available.
So why specify the provider?
Ok, I know you didn't ask that but that seemed to be where you were headed. In most cases you should not specify a provider. The general rule is to avoid specifying a provider unless you have a good reason to do so. Leaving the provider unspecified increases portability.
Unfortunately, there are some cases I've encountered where you probably need to specify the provider. The abstractions provided in the JCE just do not cover all the situations that arise in practice. If you run into one of those it's best to ask a separate question.
I'm working on a mobile App which is to be build in Android (Native) , iOS (Native) & PhoneGap. For security I'm already using SSL, but as per client requirement another encryption is to be implemented in all webservices( Mobile end and Server) . But I'm unable to implement encryption which works well in Java, Objective-C and JavaScript.
I could manage to get AES-256 working in all the platforms , but it works very slow in Android. Library used for the same was RNCryptor.
Can you please suggest me any Encryption/Decryption library which is compatible along at least Java & Objective-C.
AES-256 a correct choice and should not be a performance problem. Most cpu chips include special instructions to allow faster implementations, Apple ARM chips do as do may Intel chips. If you are going to claim that encryption is slow for an implementation you need to supply test times for all platforms, generate them and post them.
Obtaining the same results from encryption, AES-256 in this case, is simply supplying the exact same inputs with the exact required lengths and exact same options--that is all.
Providing secure encryption is more than just a key, data and an AES-256 library. There needs to be an iv, if the key is week it needs to be extended, passwords are generally extended with PBKDF2 or it's like. These require more information to be added to the encrypted data that is passed. There is also data padding such as PKCS#7. RNCryptor handles all this but for interoperability requires the other-end to use the same scheme. Then there is the issue of securing the encryption key and exchanging it with the other-side.
I am working on a system which is going to be applied in the real environment. I need to make high security mechanism for the system, one of them is encryption for user's passwords in my database.
I prefer to use one way encryption method to two way encryption, the problem is I want to choose a good algorithm which has good performance and have reasonable reasons to convince my partners why i choose one algorithm instead of other.
Can you give me some tips for doing that?
Don't just use a simple one-way hash.
Use something like PBKDF2 or bcrypt instead. I'm sure there will be good, free, off-the-shelf implementations available for Java (assuming that they're not already included in the JRE itself).
i don't know what kind of argument you're looking for but :
SHA is a good one-way hash functions.
http://en.wikipedia.org/wiki/Secure_Hash_Algorithm
Edit :
I'm using Bcrypt but maybe you should look at Scrypt (http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html)
I need to store some sensitive data by encrypting it with atleast 128 bit key. I investigated into javax.crypto package and found that there are certain Cipher names, like
PBEWithMD5AndDES or PBEWithSHA1AndDESede which provides encryption upto 56 bit and 80 bit (http://en.wikipedia.org/wiki/DESede).
I referred other guys posts but those are mainly using RSA and in my understanding RSA is generally suitable for encrypting the communication data (with private-public key pair). My need is different, I just want to store the data and retrieve it back by decrypting it. Therefore I don't need any private-public key pairs.
Please let me know if you have any idea about this.
Use Advanced Encryption Standard (AES). It supports Key lengths of 128, 192, or 256 bits.
The algorithm is simple. The Sun Java website has a section explaining how to do AES encryption in Java.
From Wikipedia...
... the Advanced
Encryption Standard (AES), also known
as Rijndael, is a block cipher adopted
as an encryption standard by the U.S.
government. It has been analyzed
extensively and is now used worldwide,
as was the case with its
predecessor, the Data Encryption
Standard (DES)...
So as a rule of thumb you are not supposed to use DES or its variants because it is being phased out.
As of now, it is better to use AES. There are other options like Twofish, Blowfish etc also. Note that Twofish can be considered as an advanced version of Blowfish.
I have had good success in the past with http://www.bouncycastle.org/ (they have a C# version as well).
You need to download and install the unlimited strength JCE policy file for your JDK. For JDK 6, it is on http://java.sun.com/javase/downloads/index.jsp at the very bottom.
Combining 3 different replies gives what I think is the correct answer.
Download encryption libraries from Bouncycastle then you need to download the "Unlimited Strength Jurisdiction Policy" from Oracle (the files are at the bottom of the download page). Make sure you read the Readme-file on how to install it.
Once you have done this, and using the sample code supplied with the Bountycastle package you should be able to encrypt your data. You can go with a tripple DES implementation, which will give you 112 bits key (often referred to as 128 bit, but only 112 of them are actually secure), or as previously stated, you can use AES. My money would be on AES.
I'm not a crypto expert by any means (so take this suggestion with a grain of salt), but I have used Blowfish before, and I think you can use it for what you need. There is also a newer algorithm by the same guy called Twofish.
Here is a website with a Java implementation, but be careful of the license (it says free for non-commercial use). You can find that link also from Bruce Schneier's website (the creator of both algorithms).
Thanks Michael, after trying out many things in JCE, I finally settled for bouncycastle.
JCE supports AES for encryption and PBE for password based encryption but it does not support combination of both. I wanted the same thing and that I found in bouncycastle.
The example is at : http://forums.sun.com/thread.jspa?messageID=4164916