S/MIME in Java without JCE - java

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.

Related

Using providers in Java AES encryption

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.

Is there a way to set up random access to encrypted data in Android?

I'm currently trying to provide a transparent encryption/decryption layer to files stored on an Android device. I need random access to each of these files (necessary for search algorithm). The layer needs to provide either a RandomAccessFile or a FileChannel to the rest of the program.
My (very) basic understanding of crypto suggests that certain cipher modes like ECB, CTR, XEX, and XTR could facilitate random access, but I'd rather use somebody else's tool before I reinvent the wheel. Much better to leave crypto to the experts.
An ideal solution would be an encrypted disk image that I could access using a Java library, but I haven't found anything that I could use for Android.
Is there a way for me to provide random access to encrypted files? This feels like something that a lot of people would want in their apps!
Random read access is easy: use CTR, but make sure you have correct key and nonce usage. Random write access could be just as easy, although with CTR you are leaking information in time if you change any block. So if an attacker simply gets a single view of one file then you would be OK, otherwise you directly leak information about the plain text.
You've got a specific usage scenario. If there are any libs that do this for you I haven't seen them yet. Furthermore, the key management is usually application specific too. I am afraid you will have to deal with threat scenarios.
ECB should not be used for related information such as strings or files. XEX (or XTS for that matter) is normally not available in Java crypto libraries (such as the Oracle JCE or Bouncy).

Why do people use bouncycastle instead of Java's built in JCE provider? What is the difference?

Why do people use bouncycastle instead of Java Cryptography Extension? What is the difference?
BouncyCastle has many more cipher suites and algorithms than the default JCE provided by Sun.
In addition to that, BouncyCastle has lots of utilities for reading arcane formats like PEM and ASN.1 that no sane person would want to rewrite themselves.
Bouncy Castle is Australian in origin, and therefore is not subject to the Export of cryptography from the United States.
It is useful if you are outside the United States and you need to manage key sizes grater than permitted by such that restriction. In that case you are not permitted to use software from United States for that.
On server or desktop, I don't see any reason to use BC unless you have to deal with some legacy ciphers or formats not supported by Sun JCE.
However, many JREs don't come with a JCE provider, like on mobile or embedded environments. BC comes handy in such cases.

Best way to encrypt a directory of files?

I need to programatically encrypt a directory of files, like in a .zip or whatever. Preferably password protected obviously.
How can I accomplish this, and WHAT IS the BEST encryption way to do it, if applicable?
Programming language doesn't matter. I am dictioned in all syntax.
How can I accomplish this, and WHAT IS
the BEST encryption way to do it, if
applicable?
tar and gzip the directory.
Generate a random bit stream of equal size to the file
Run bitwise XOR on the streams
Only truly secure method is a truly random one time pad.
I still say 7-zip is the answer. It hasn't been "cracked".
The OpenSSL library has a variety of block cipher implementations including the well-known AES. It has both a function-call interface (for use with languages like C/C++) and a program-call interface (for use in shell scripts). http://www.openssl.org/
4096-Bit (Open)PGP: 'Pretty Good' Privacy !
GnuPG is the GNU project's complete and free implementation of the OpenPGP standard as defined by RFC4880 . GnuPG allows to encrypt and sign your data and communication, features a versatile key managment system as well as access modules for all kind of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available. Version 2 of GnuPG also provides support for S/MIME.
libgcrypt:
http://www.gnupg.org/related_software/libraries.en.html
Edit:
BouncyCastle now has OpenPGP support.
http://www.bouncycastle.org/
Use AES. You'll find implementations in your favourite programming language by asking google for AES encryption + myfavouritelanguage.
If you're using .NET, why not use a free compression framework (http://www.icsharpcode.net/OpenSource/SharpZipLib/) that supports Encryption?

Are there any other open source JCE libraries besides BouncyCastle?

I am looking for open source JCE libraries that implement some of the more esoteric encryption algorithms so that I can study their implementation. I would be especially interested in ones that implement Identity Based Encryption (IBE) as published by Stanford.
Cryptix (not sure what state its in at the moment but it was high quality when I used it last):
http://www.cryptix.org
http://sourceforge.net/projects/cryptix
GNU Classpath also has their own JCE implementation, however, whether they support IBE is another story.

Categories