Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development Knowledge Base

PKCS5 Padding In BlackBerry 10

by Retired on ‎11-08-2012 10:33 AM (2,783 Views)

PKCS5 (and PKCS7) padding is common in protocols and encryption schemes – but notably absent from the ‘Certicom®’ crypto APIs on BlackBerry® 10.

There are a couple of reasons it isn’t there:

  1. It’s easy to do yourself
  2. It’s not very secure

It’s Easy To Do Yourself

 

Under the scheme;

  • padding must always be included.
  • padding is appended to the plain text to create a message whose length is an integral multiple of the cipher’s block size. For some messages this means extending by another whole block – just for the padding.
  • the number of bytes of padding is between 1 and the cipher’s block size. eg:
    • AES – will have between 1 and 16 bytes of padding.
    • DES – will have between 1 and 8 bytes of padding.
  • each byte in the padding – is the number of bytes of padding.
    • {1} is valid.
    • {4,4,4,4} is valid.
    • {1,2,3} is NOT valid.
  • verifying is more work than padding.

It’s Not Very Secure

 

If you decrypt random data with a random key – the probability of the last byte being 1 is around 1/256. ie: don’t rely on a PKCS5 padding check to verify your data.

 

Sample Code

Here’s some code showing you how you could pad yourself in Qt®.

#include <QByteArray>
#include <QDebug>
#include <assert.h>

/**
 * PKCS#5 pad the given buffer for the given block size.
 * @param buffer the buffer to pad.
 * @param blockSize the block size to use.
*/
void pad(QByteArray & buffer, const int blockSize) {
    // Find the padding value to use.
    const char padValue = (char)(blockSize - (buffer.length() % blockSize));

    // Append the padding bytes.
    for (int i=0; i<padValue; ++i) {
        buffer+=padValue;
    }
}

/**
 * Verify that the PKCS#5 padding in the given buffer is correct for the given
 * block size, and remove it.
 * @param buffer The buffer to use. Should be plaintext followed by padding.
 * @param blockSize The block size to use.
 * @return true iff the padding was correct and removed.
 */
bool verifyAndRemovePadding(QByteArray & buffer, const int blockSize) {
    int offset = buffer.length();

    // Check if met the minimum 1 block.
    if (offset < blockSize) {
        return false;
    }
    // Check to see if integral number of blocks.
    if (offset % blockSize != 0) {
        return false;
    }

    const char padValue = buffer[--offset];

    // Check to see if pad value is within allowed range.
    if (padValue<1 || padValue > blockSize) {
        return false;
    }

    // Check remaining padding bytes.
    for (int i=1; i<padValue; ++i) {
        if (buffer[--offset]!=padValue) {
            return false;
        }
    }

    // Remove the padding.
    buffer.chop(padValue);

    return true;
}

/**
 * Run some basic tests against the pad and verify functions.
 */
int main(int argc, char *argv[])
{
    const int blockSize = 16;

    // Positive test cases.
    for (int i=0; i<20; ++i) {
        QByteArray b;
        for (int j=0; j<i; ++j) {
            b.append(i+j*i);
        }
        QByteArray original(b);

        pad(b,blockSize);

        qDebug() << b.toHex();

        assert(b.length()!=0);
        assert(b.length()%blockSize==0);
        assert(b.length()>i);
        assert(((int)b[b.length()-1])==(blockSize-(i%blockSize)));

        assert(verifyAndRemovePadding(b,blockSize));
        assert(original==b);
    }

    // Negative test cases.
    QByteArray empty;
    assert(!verifyAndRemovePadding(empty,blockSize));

    // Good padding - but not a block
    QByteArray goodPaddingButNotABlock(blockSize-1,blockSize-1);
    assert(!verifyAndRemovePadding(goodPaddingButNotABlock,blockSize));

    // Bad padding
    QByteArray badSequence(blockSize,blockSize);
    badSequence[3] = 5;
    assert(!verifyAndRemovePadding(badSequence,blockSize));

    // Bad length
    QByteArray badPadLength(blockSize-1,blockSize-1);
    badPadLength.append((char)0);
    assert(!verifyAndRemovePadding(badPadLength,blockSize));

    badPadLength[badPadLength.length()-1]=blockSize+1;
    assert(!verifyAndRemovePadding(badPadLength,blockSize));

    return 0;
}

 

Contributors
Users Online
Currently online: 17 members 1,855 guests
Please welcome our newest community members: