Skip to content

Instantly share code, notes, and snippets.

@bitbeans
Last active July 19, 2019 20:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bitbeans/fb2bf80a47b1af31b07c to your computer and use it in GitHub Desktop.
Save bitbeans/fb2bf80a47b1af31b07c to your computer and use it in GitHub Desktop.
PKCS7 padding in C#
/// <summary>
/// Removes the Pkcs7 padding of an array.
/// </summary>
/// <param name="paddedByteArray">The padded array.</param>
/// <returns>The unpadded array.</returns>
/// <exception cref="OverflowException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public static byte[] RemovePkcs7Padding(byte[] paddedByteArray)
{
if (paddedByteArray == null)
{
throw new ArgumentNullException("paddedByteArray", "paddedByteArray can not be null");
}
var last = paddedByteArray[paddedByteArray.Length - 1];
if (paddedByteArray.Length <= last)
{
// there is nothing to unpad
return paddedByteArray;
}
return SubArray(paddedByteArray, 0, (paddedByteArray.Length - last));
}
/// <summary>
/// Fill up an array with Pkcs7 padding.
/// </summary>
/// <param name="data">The source array.</param>
/// <param name="paddingLength">The length of the padding.</param>
/// <returns>The padded array.</returns>
/// <exception cref="OverflowException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static byte[] AddPkcs7Padding(byte[] data, int paddingLength)
{
if (data.Length > 256)
{
throw new ArgumentOutOfRangeException("data", "data must be <= 256 in length");
}
if (paddingLength > 256)
{
throw new ArgumentOutOfRangeException("paddingLength", "paddingLength must be <= 256");
}
if (paddingLength <= data.Length)
{
// there is nothing to pad
return data;
}
var output = new byte[paddingLength];
Buffer.BlockCopy(data, 0, output, 0, data.Length);
for (var i = data.Length; i < output.Length; i++)
{
output[i] = (byte) (paddingLength - data.Length);
}
return output;
}
/// <summary>
/// Extract a part of a byte array from another byte array.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arr">A byte array.</param>
/// <param name="start">Position to start extraction.</param>
/// <param name="length">The length of the extraction started at start.</param>
/// <returns>A part with the given length of the byte array.</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static T[] SubArray<T>(T[] arr, int start, int length)
{
var result = new T[length];
Buffer.BlockCopy(arr, start, result, 0, length);
return result;
}
@pernicek
Copy link

pernicek commented Sep 8, 2016

This code may fail while deleting padding as the check if the array contains padded elements is not 100%. This code fixes it - it checks all the padding bytes for correct value:

public static byte[] RemovePkcs7Padding(byte[] paddedByteArray)
{
    if (paddedByteArray == null) {
        throw new ArgumentNullException("paddedByteArray", "paddedByteArray can not be null");
    }

    dynamic last = paddedByteArray(paddedByteArray.Length - 1);
    if (paddedByteArray.Length <= last) {
        // there is nothing to unpad
        return paddedByteArray;
    }

    for (int i = paddedByteArray.Length - 2; i >= paddedByteArray.Length - last; i += -1) {
        if (paddedByteArray(i) != last) {
            return paddedByteArray;
        }
    }

    return SubArray(paddedByteArray, 0, (paddedByteArray.Length - last));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment