2
0
forked from sim0n00ps/OF-DL
OF-DL/OF DL/Crypto/Padding.cs

127 lines
3.4 KiB
C#

using System.Security.Cryptography;
namespace OF_DL.Crypto;
public class Padding
{
public static byte[] AddPKCS7Padding(byte[] data, int k)
{
int m = k - data.Length % k;
byte[] padding = new byte[m];
Array.Fill(padding, (byte)m);
byte[] paddedBytes = new byte[data.Length + padding.Length];
Buffer.BlockCopy(data, 0, paddedBytes, 0, data.Length);
Buffer.BlockCopy(padding, 0, paddedBytes, data.Length, padding.Length);
return paddedBytes;
}
public static byte[] RemovePKCS7Padding(byte[] paddedByteArray)
{
byte last = paddedByteArray[^1];
if (paddedByteArray.Length <= last)
{
return paddedByteArray;
}
return SubArray(paddedByteArray, 0, paddedByteArray.Length - last);
}
public static T[] SubArray<T>(T[] arr, int start, int length)
{
T[] result = new T[length];
Buffer.BlockCopy(arr, start, result, 0, length);
return result;
}
public static byte[] AddPSSPadding(byte[] hash)
{
int modBits = 2048;
int hLen = 20;
int emLen = 256;
int lmask = 0;
for (int i = 0; i < 8 * emLen - (modBits - 1); i++)
{
lmask = (lmask >> 1) | 0x80;
}
if (emLen < hLen + hLen + 2)
{
return null;
}
byte[] salt = new byte[hLen];
new Random().NextBytes(salt);
byte[] m_prime = Enumerable.Repeat((byte)0, 8).ToArray().Concat(hash).Concat(salt).ToArray();
byte[] h = SHA1.Create().ComputeHash(m_prime);
byte[] ps = Enumerable.Repeat((byte)0, emLen - hLen - hLen - 2).ToArray();
byte[] db = ps.Concat(new byte[] { 0x01 }).Concat(salt).ToArray();
byte[] dbMask = MGF1(h, emLen - hLen - 1);
byte[] maskedDb = new byte[dbMask.Length];
for (int i = 0; i < dbMask.Length; i++)
{
maskedDb[i] = (byte)(db[i] ^ dbMask[i]);
}
maskedDb[0] = (byte)(maskedDb[0] & ~lmask);
byte[] padded = maskedDb.Concat(h).Concat(new byte[] { 0xBC }).ToArray();
return padded;
}
public static byte[] RemoveOAEPPadding(byte[] data)
{
int k = 256;
int hLen = 20;
byte[] maskedSeed = data[1..(hLen + 1)];
byte[] maskedDB = data[(hLen + 1)..];
byte[] seedMask = MGF1(maskedDB, hLen);
byte[] seed = new byte[maskedSeed.Length];
for (int i = 0; i < maskedSeed.Length; i++)
{
seed[i] = (byte)(maskedSeed[i] ^ seedMask[i]);
}
byte[] dbMask = MGF1(seed, k - hLen - 1);
byte[] db = new byte[maskedDB.Length];
for (int i = 0; i < maskedDB.Length; i++)
{
db[i] = (byte)(maskedDB[i] ^ dbMask[i]);
}
int onePos = BitConverter.ToString(db[hLen..]).Replace("-", "").IndexOf("01") / 2;
byte[] unpadded = db[(hLen + onePos + 1)..];
return unpadded;
}
private static byte[] MGF1(byte[] seed, int maskLen)
{
SHA1 hobj = SHA1.Create();
int hLen = hobj.HashSize / 8;
List<byte> T = new();
for (int i = 0; i < (int)Math.Ceiling(maskLen / (double)hLen); i++)
{
byte[] c = BitConverter.GetBytes(i);
Array.Reverse(c);
byte[] digest = hobj.ComputeHash(seed.Concat(c).ToArray());
T.AddRange(digest);
}
return T.GetRange(0, maskLen).ToArray();
}
}