It seems the RIM Crypto API provides for only PKCS5 Padding mode for symmetric encryption (3Des) - as far as I know. I'm working with the JDE 4.6.0.
I'm trying to provide cryptography for a blackbery app which needs to be compatible with existing services which already use NoPadding with the standard Java security开发者_开发知识库 API.
Is there a way to extend the API to provide for the lacking PADDING modes, or some other hack, to achieve this?
Based on what you've told me, I would use the encrypt function of TripleDESCBCEncryptorEngine to encrypt your blocks.
There is a version of the function that can encrypt multiple blocks at once by specifying the number of blocks.
Here is a reference to that function.
It looks very straightforward, you just pass the key and the IV into the constructor and then proceed to make calls to .encrypt to encrypt the data.
Similarly there is a TripleDESCBCDecryptorEngine here.
I admit to not being familiar at all with the RIM crypto API, but just from reading the documentation it appears just using the the BlockEncryptorEngine.encrypt()
method gives you the same functionality as the JCE NoPadding tranformations for block ciphers. So in your example that would be TripleDESEncryptorEngine
.
If you are using CBC chaining mode and can arrange for your input data to have a length multiple of the block size (i.e. multiple of eight, when expressed in bytes, if the block cipher is 3DES) then you just have to remove the last block of the encrypted output.
In CBC encryption, input data (m) is first padded into a message which has a length multiple of the block size (with PKCS#5, by adding between 1 and b bytes, where b is the block length, b=8 for 3DES); then it is split into successive b-bytes blocks. Each of those blocks yields an encrypted block of the same size: the encrypted block for message block i is the result of 3DES applied on the bitwise XOR of message block i and encrypted block i-1. Consequently, if the original message m has a length multiple of b, then PKCS#5 padding adds b bytes, i.e. a full block. By removing the last encrypted block, you obtain what you would have got with no padding at all.
Decryption might be trickier. If the RIM API is stream-oriented (if it can gives you some plaintext bytes before having the whole message) then you can feed it with null trailing bytes until it returned you all your message (the extra null bytes will decrypt into pure random-looking junk, just discard it). If the RIM API is message-oriented, then you will have to use your knowledge of the secret key to rebuild a valid "last block" (the one which was you removed during encryption). Namely, with 3DES, this would mean the following: if z is the last encrypted block of the message (the one with "no padding"), then you encrypt an empty message (of no byte at all) with the same key, using z as "initial value" (IV). This should result in a single b-byte block, which you just append to the encrypted message. The effect of that extra block is that the decryption engine will "see" a proper PKCS#5 padding, and transparently remove it, yielding the data you expect.
All of the above assumes that you are using CBC, which is the most common chaining mode, among those which require padding.
精彩评论