S/MIME in Java without JCE
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.开发者_Python百科 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.
精彩评论