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.
Related
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.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
The community reviewed whether to reopen this question 8 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm working on a program that needs to store binary information encrypted at rest. Unfortunately, I can't seem to find a resource that explains which encryption schemes are best for different applications.
Since encryption is complicated and I'm not an expert, I've decided to use a library called Jasypt that wraps Java's built-in encryption functions. To figure out what algorithms are available to me, I wrote a few unit tests.
The first test calls Jasypt's AlgorithmRegistry.getAllPBEAlgorithms() function and lists out all available encryption algorithms:
PBEWITHHMACSHA1ANDAES_128
PBEWITHHMACSHA1ANDAES_256
PBEWITHHMACSHA224ANDAES_128
PBEWITHHMACSHA224ANDAES_256
PBEWITHHMACSHA256ANDAES_128
PBEWITHHMACSHA256ANDAES_256
PBEWITHHMACSHA384ANDAES_128
PBEWITHHMACSHA384ANDAES_256
PBEWITHHMACSHA512ANDAES_128
PBEWITHHMACSHA512ANDAES_256
PBEWITHMD5ANDDES
PBEWITHMD5ANDTRIPLEDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40
At runtime, Jasypt will throw an EncryptionOperationNotPossibleException if you try to use an algorithm that for some reason isn't supported or violates Java's encryption rules. Interestingly, if I attempt to use each of the 'available' algorithms to encrypt and then decrypt some arbitrary data, and only print out the ones that don't throw that exception, I get this slimmed down list:
PBEWITHMD5ANDDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40
The list of available algorithms can be expanded by pulling in the BouncyCastle JCE and registering it by executing Security.addProvider(new BouncyCastleProvider()). If I repeat the previous test after doing this, I get a much bigger list of algorithms to choose from:
PBEWITHMD2ANDDES
PBEWITHMD5AND128BITAES-CBC-OPENSSL
PBEWITHMD5AND192BITAES-CBC-OPENSSL
PBEWITHMD5AND256BITAES-CBC-OPENSSL
PBEWITHMD5ANDDES
PBEWITHMD5ANDRC2
PBEWITHSHA1ANDDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40
PBEWITHSHA256AND128BITAES-CBC-BC
PBEWITHSHA256AND192BITAES-CBC-BC
PBEWITHSHA256AND256BITAES-CBC-BC
PBEWITHSHAAND128BITAES-CBC-BC
PBEWITHSHAAND128BITRC2-CBC
PBEWITHSHAAND128BITRC4
PBEWITHSHAAND192BITAES-CBC-BC
PBEWITHSHAAND2-KEYTRIPLEDES-CBC
PBEWITHSHAAND256BITAES-CBC-BC
PBEWITHSHAAND3-KEYTRIPLEDES-CBC
PBEWITHSHAAND40BITRC2-CBC
PBEWITHSHAAND40BITRC4
PBEWITHSHAANDIDEA-CBC
PBEWITHSHAANDTWOFISH-CBC
Unfortunately, now I have no idea which of these many algorithms is most appropriate for my application. I have an inkling that AES is the right way to go, and it looks like PBEWITHSHA256AND256BITAES-CBC-BC is the AES implementation with the longest key length, but I don't know where to go to confirm that suspicion.
Which of these schemes would provide the highest security levels and which have obvious security issues?
EDIT: I want to be able to distribute my code without requiring the end user to install the unlimited cryptography files, as that will almost certainly be beyond the capabilities of not so tech savvy users. What I really want is the strongest encryption that I can get without using the unlimited strength jurisdiction files.
First of all you should install the unlimited cryptography files from Oracle*. After doing so you should have fewer EncryptionOperationNotPossibleExceptions and higher security levels should become available.
Furthermore, for the highest level encryption possible I would not use JaSypt at all, because it doesn't seem to provide any integrity checking or authentication of ciphertext. For just confidentiality that doesn't seem to matter. But in practice you'd need to check that against your threat model.
If you'd decide to use JaSypt (which I personally dislike) you should probably go for PBEWITHHMACSHA512ANDAES_256 as highest level possibility. Make sure you understand PBKDF2 and work factors (iteration count, e.g. setKeyObtentionIterations.
You don't need Bouncy Castle. AES is considered secure; all Bouncy Castle does - for your example that uses JaSypt - is adding obscure ciphers. In the above list, everything other than AES is less secure than AES.
* This is an old answer, generally the unlimited cryptography extensions aren't necessary anymore
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'm trying to write an applet that would sign e-mail with S/MIME.
Obviously I want to make one small jar with only the required stuff.
Obviously the Java way of doing that involves having a huge sacred signed Bouncy Castle JCE jar around.
The question is: What's the easiest way of getting S/MIME without touching JCE and having it complain about "authenticating" "providers"? Maybe there is a S/MIME implementation that doesn't depend on JCE? Maybe it is possible to use Bouncy Castle S/MIME using their lightweight API without touching JCE? Maybe there is any other way?
It is obvious to me that nothing can prevent a pure-java open source crypto algorithms from working regardless of whether Sun approves, so it's not a question of theoretical possibility, rather: which way is the least painful?
Of course, I can always go ugly early by grabbing Bouncy Castle pure-java JCE implementation, renaming its packages to java.security1, and making any changes I want - but this way looks too painful right now.
UPDATE My current problem with using Bouncy Castle directly: I try to load keys from keystore, which involves using SecretKeyFactory, which in turn rejects my Bouncy Castle build.
BC S/MIME is written over the CMS package, so the question really devolves to modifying the CMS package so all the crypto is done using the light-weight classes.
Something similar has been done already, more-or-less successfully, for the .NET version of Bouncy Castle. We're trying (admittedly it's a slow process) to refactor the Java version so the CMS stuff can work with either JCE or lightweight. The same issue affects other parts of the BC API too e.g. the PKCS#12 keystore is built into the JCE provider, the OpenPGP package is written to JCE, etc. The .NET ports of these rewrote them to the light-weight API also.
Your problem is probably simpler than the general case though. Presumably you only need the CMSSignedDataGenerator and supporting classes. You probably don't need all the myriad variations of addSigner or generate. If you just decide on your digest/signature algorithms up front, then all the provider stuff will be easy to replace with hardcoded calls to specific lightweight implementations.
Instead of a keystore, maybe you could get away with just storing a single private key in a PKCS#8 file (PEM encoded perhaps). Similarly for the certificate.
It's pretty straightforward to sign messages without using JCE.
The real problem was reading PKCS#12 keys.
I did this:
* Copied JDKPKCS12KeyStore class over.
* Everywhere in it, replaced Security.getInstance() with bcProvider.getService().newInstance() (which returns Spi-s)
* In those Spi-s (in BC sources) made required methods public instead of protected.
It looks like a hack, but seems to actually work.
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