2

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?

Olaseni
  • 7,698
  • 16
  • 44
  • 68
  • Can you explain more here? What block cipher mode are you using? If you are using CBC, padding really isn't an option, you must always encrypt/decrypt a multiple of the block size. You can either use PKCS5, fill the rest of the block with 0's, or leave the rest of the data as random garbage and ignore it. CBC encrypts the whole block or nothing at all. There are block cipher modes that don't require padding (such as counter mode). They essentially become stream ciphers at that point. – Luke Mar 25 '11 at 18:54
  • I'm using CBC, and I manually pad the bytes into multiples of the block size(8). I'm looking for a workaround the API that allows for this - perhaps without a formatterEngine? – Olaseni Mar 25 '11 at 20:19

3 Answers3

1

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.

Luke
  • 3,742
  • 4
  • 31
  • 50
  • How is this different than what I posted 17 hours before you? I'm happy to share credit but really... – President James K. Polk Mar 25 '11 at 23:50
  • The functions and classes you suggest to him are not using CBC. I'm actually not sure what block cipher mode it's using, but it doesn't take an initial vector so I'm going to assume it's using ECB, which is full of security issues and will not be compatible with the CBC that his Java code is using. I took the time to ask questions so that I could give the OP an appropriate answer rather than trying to guess at what he was looking for and firing off an answer as quickly as possible. If the OP likes yours better he can pick yours. – Luke Mar 26 '11 at 16:35
0

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.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • This won't work with the CBC he's using. These functions do not take an initial vector, therefore they are probably using ECB. The messages less than or equal to 1 block would be fine if the IV was 0, but anything over 1 block or using a non 0 IV would not decrypt/encrypt properly. – Luke Mar 26 '11 at 16:38
0

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.

Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189