public void EmptyMask() { // pretty much useless but supported byte[] random = { 0x01 }; byte[] mask = pkcs1.GenerateMask(random, 0); Assertion.AssertEquals("PKCS1MaskGenerationMethod Empty Mask", 0, mask.Length); }
public byte[] Decode(HashAlgorithm hash, PKCS1MaskGenerationMethod mgf, byte[] encodedData, int encodedDataOffset, int encodedDataCount) { Validate.AnArray(encodedData, encodedDataOffset, encodedDataCount); if (encodedDataCount < mSeedSize) { // TODO throw an exception throw new Exception("encodedData is not long enough (" + encodedDataCount + " bytes) as the seed is " + mSeedSize + " bytes"); } byte[] maskedSeed = new byte[mSeedSize]; byte[] maskedDB = new byte[encodedDataCount - mSeedSize]; Buffer.BlockCopy(encodedData, encodedDataOffset, maskedSeed, 0, maskedSeed.Length); Buffer.BlockCopy(encodedData, encodedDataOffset + maskedSeed.Length, maskedDB, 0, encodedDataCount - maskedSeed.Length); byte[] seedMask = mgf.GenerateMask(maskedDB, maskedSeed.Length); mSeed = new byte[maskedSeed.Length]; for (int j = 0; j < maskedSeed.Length; j++) { mSeed[j] = (byte)(maskedSeed[j] ^ seedMask[j]); } //System.Diagnostics.Debug.WriteLine("Seed was " + ByteArrayToString(seed)); byte[] dbMask = mgf.GenerateMask(mSeed, maskedDB.Length); byte[] data = maskedDB; for (int i = 0; i < maskedDB.Length; i++) { data[i] ^= dbMask[i]; } //System.Diagnostics.Debug.WriteLine("Data was " + ByteArrayToString(data)); return(data); }
public byte[] Encode(HashAlgorithm hash, PKCS1MaskGenerationMethod mgf, RandomNumberGenerator rng, byte[] data, int dataOffset, int dataCount) { Validate.AnArray(data, dataOffset, dataCount); //int lHash = hash.HashSize / 8; int lEM = mSeedSize + data.Length; //System.Diagnostics.Debug.WriteLine("Data was " + ByteArrayToString(data)); // Inspired by RFC3447 https://www.ietf.org/rfc/rfc3447.txt, from 7.1.1, step 2 // BUT THIS IMPLEMENTATION IS NOT COMPLIANT WITH THE STANDARD!!! // I have removed the static hash (PS) and static bytes // a. Not putting the hash of the label in the encoding //hash.ComputeHash(new byte[0]); ////byte[] DB = new byte[lEM - lHash]; //byte[] DB = new byte[lHash + 1 + data.Length]; byte[] DB = new byte[dataCount]; Buffer.BlockCopy(data, dataOffset, DB, 0, dataCount); // b. No need to calculate PS as we will always choose lengths so it is zero // c. Concatenate lHash, PS, 0x01, data. For this impl nothing to copy //Buffer.InternalBlockCopy(hash.Hash, 0, DB, 0, lHash); ////DB[DB.Length - data.Length - 1] = 1; //DB[lHash + 1] = 1; ////Buffer.InternalBlockCopy(data, 0, DB, DB.Length - data.Length, data.Length); //Buffer.InternalBlockCopy(data, 0, DB, (lHash + 1) + 1, data.Length); // d. Generate random seed. // Another departure from the RFC, we'll let the seed size be different from the hash size. if (null == mSeed) { mSeed = new byte[mSeedSize]; rng.GetBytes(mSeed); } //System.Diagnostics.Debug.WriteLine("Seed was " + ByteArrayToString(seed)); // e. Create dbMask byte[] dbMask = mgf.GenerateMask(mSeed, DB.Length); // f. Mask DB for (int i = 0; i < DB.Length; i++) { DB[i] ^= dbMask[i]; } // g. Create seedMask byte[] seedMask = mgf.GenerateMask(DB, mSeedSize); // h. Mask the seed and create maskedSeed byte[] maskedSeed = (byte[])mSeed.Clone(); for (int j = 0; j < maskedSeed.Length; j++) { maskedSeed[j] ^= seedMask[j]; } // i. Create the encoded message EM byte[] EM = new byte[lEM]; Buffer.BlockCopy(maskedSeed, 0, EM, 0, maskedSeed.Length); Buffer.BlockCopy(DB, 0, EM, maskedSeed.Length, DB.Length); return(EM); }
private byte[] RestoreSingleOAEPBlock(byte[] p_data, int p_offset, int p_count, int p_K) { byte[] x_maskedSeed = new byte[o_lhash.Length]; Array.Copy(p_data, p_offset + 1, x_maskedSeed, 0, o_lhash.Length); byte[] x_maskedDB = new byte[p_K - o_lhash.Length - 1]; Array.Copy(p_data, p_offset + 1 + o_lhash.Length, x_maskedDB, 0, x_maskedDB.Length); byte[] x_seedMask = o_mask_generator.GenerateMask(x_maskedDB, o_lhash.Length); byte[] x_seed = (new BigInteger(x_maskedSeed) ^ new BigInteger(x_seedMask)).getBytes(); byte[] x_dbMask = o_mask_generator.GenerateMask(x_seed, p_K - o_lhash.Length - 1); byte[] x_DB = (new BigInteger(x_maskedDB) ^ new BigInteger(x_dbMask)).getBytes(); for (int i = 0; i < o_lhash.Length; i++) { if (x_DB[i] != o_lhash[i]) { throw new CryptographicException("Decryption Error"); } } if (p_data[0] != 0) { throw new CryptographicException("Decryption Error"); } int x_index = -1; for (int i = o_lhash.Length; i < x_DB.Length; i++) { if (x_DB[i] == 0x01) { x_index = i + 1; break; } else if (x_DB[i] != (byte)0x00) { throw new CryptographicException("Decryption Error"); } } if (x_index == -1) { throw new CryptographicException("Decryption Error"); } byte[] x_message = new byte[x_DB.Length - x_index]; Array.Copy(x_DB, x_index, x_message, 0, x_message.Length); return(x_message); }
public static Boolean Test() { bool bRes = true; Console.WriteLine("Easy as"); PKCS1MaskGenerationMethod mgm = new PKCS1MaskGenerationMethod(); Console.WriteLine("One..."); byte[] seed1 = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; byte[] res1 = mgm.GenerateMask(seed1, 4); if ((res1 == null) || (res1.Length != 4)) { Console.WriteLine("ERROR while attempt #1"); bRes = false; } Console.WriteLine("Two..."); mgm.HashName = "MD5"; byte[] seed2 = new byte[2] { 4, 3 }; byte[] res2 = mgm.GenerateMask(seed2, 16); if ((res2 == null) || (res2.Length != 16)) { Console.WriteLine("ERROR while attempt #2"); bRes = false; } Console.WriteLine("Three..."); mgm.HashName = "SHA1"; byte[] seed3 = new byte[100000]; for (int i = 0; i < 100000; i++) { seed3[i] = (byte)(i % 256); } byte[] res3 = mgm.GenerateMask(seed3, 65536); if ((res3 == null) || (res3.Length != 65536)) { Console.WriteLine("ERROR while attempt #3"); bRes = false; } return(bRes); }
public static void GenerateMask_InvalidHashName_Throws(string hashName) { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); pkcs1.HashName = hashName; Assert.Throws <CryptographicException>(() => pkcs1.GenerateMask(new byte[] { 0 }, 1)); }
public static void NegativeReturnParameterTest() { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); byte[] random = { 0x01 }; Assert.Throws <OverflowException>(() => pkcs1.GenerateMask(random, -1)); }
public static void EmptyMaskTest() { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); byte[] random = { 0x01 }; byte[] mask = pkcs1.GenerateMask(random, 0); Assert.Equal(0, mask.Length); }
public static Boolean Test() { bool bRes = true; Console.WriteLine("Easy as"); PKCS1MaskGenerationMethod mgm = new PKCS1MaskGenerationMethod(); Console.WriteLine("One..."); byte[] seed1 = new byte[10] {0,1,2,3,4,5,6,7,8,9}; byte[] res1 = mgm.GenerateMask(seed1, 4); if ( (res1 == null) || (res1.Length != 4) ) { Console.WriteLine("ERROR while attempt #1"); bRes = false; } Console.WriteLine("Two..."); mgm.HashName = "MD5"; byte[] seed2 = new byte[2] {4,3}; byte[] res2 = mgm.GenerateMask(seed2, 16); if ( (res2 == null) || (res2.Length != 16) ) { Console.WriteLine("ERROR while attempt #2"); bRes = false; } Console.WriteLine("Three..."); mgm.HashName = "SHA1"; byte[] seed3 = new byte[100000]; for(int i=0; i<100000; i++) seed3[i] = (byte)(i%256); byte[] res3 = mgm.GenerateMask(seed3, 65536); if ( (res3 == null) || (res3.Length != 65536) ) { Console.WriteLine("ERROR while attempt #3"); bRes = false; } return bRes; }
private byte[] CreateSingleOAEPBlock(byte[] p_data, int p_offset, int p_count, int p_K) { byte[] x_PS = new byte[p_K - p_count - (2 * o_lhash.Length) - 2]; byte[] x_DB = new byte[o_lhash.Length + x_PS.Length + 1 + p_count]; Array.Copy(o_lhash, 0, x_DB, 0, o_lhash.Length); Array.Copy(x_PS, 0, x_DB, o_lhash.Length, x_PS.Length); x_DB[o_lhash.Length + x_PS.Length] = 0x01; Array.Copy(p_data, p_offset, x_DB, o_lhash.Length + x_PS.Length + 1, p_count); BigInteger x_temp = new BigInteger(); x_temp.genRandomBits(o_lhash.Length * 8, o_random); byte[] x_seed = x_temp.getBytes(); byte[] x_dbMask = o_mask_generator.GenerateMask(x_seed, p_K - o_lhash.Length - 1); byte[] x_maskedDB = new byte[x_DB.Length]; byte[] x_temp_arr = (new BigInteger(x_DB) ^ new BigInteger(x_dbMask)).getBytes(); Array.Copy(x_temp_arr, 0, x_maskedDB, x_maskedDB.Length - x_temp_arr.Length, x_temp_arr.Length); byte[] x_seedMask = o_mask_generator.GenerateMask(x_maskedDB, o_lhash.Length); byte[] x_maskedSeed = (new BigInteger(x_seed) ^ new BigInteger(x_seedMask)).getBytes(); byte[] x_EM = new byte[1 + o_lhash.Length + x_DB.Length]; Array.Copy(x_maskedSeed, 0, x_EM, x_EM.Length - x_DB.Length - x_maskedSeed.Length, x_maskedSeed.Length); Array.Copy(x_maskedDB, 0, x_EM, x_EM.Length - x_maskedDB.Length, x_maskedDB.Length); return(x_EM); }
public static void GenerateMaskTest_MD5() { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); pkcs1.HashName = "MD5"; byte[] seed = { 0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34, 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2, 0xf0, 0x6c, 0xb5, 0x8f }; int LengthDB = 107; byte[] expectedDBMask = { 0xF2, 0x3F, 0x56, 0x5C, 0xE3, 0x7D, 0x61, 0x6E, 0x9E, 0x39, 0x22, 0x4F, 0x8C, 0x67, 0xE8, 0xFE, 0xBD, 0xD0, 0x30, 0xC2, 0x3B, 0x81, 0x6A, 0x1B, 0x9B, 0xB1, 0xC1, 0xEE, 0x13, 0xBF, 0x48, 0x72, 0x8, 0xD2, 0x5A, 0xE3, 0x76, 0xAD, 0x53, 0x6F, 0xED, 0x25, 0x24, 0x66, 0xB3, 0xBF, 0xE9, 0x6B, 0x53, 0xFA, 0x66, 0x3, 0x3, 0xE4, 0x77, 0xD, 0xE3, 0xF0, 0x4B, 0xBB, 0xF3, 0x93, 0x7E, 0x5C, 0x98, 0x35, 0x2A, 0x53, 0xCE, 0xEE, 0xDC, 0x6B, 0xDC, 0x9B, 0xEB, 0xD9, 0xC1, 0xA, 0x87, 0x17, 0x83, 0x26, 0x4B, 0x87, 0x23, 0xD2, 0xA9, 0x23, 0xDD, 0x1E, 0x6B, 0x38, 0x67, 0x37, 0xED, 0x9A, 0xD1, 0x1A, 0x20, 0xE6, 0x6A, 0xAB, 0xDE, 0xFD, 0x3E, 0x35, 0x42 }; byte[] dbMask = pkcs1.GenerateMask(seed, LengthDB); Assert.Equal(expectedDBMask, dbMask); byte[] DB = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd4, 0x36, 0xe9, 0x95, 0x69, 0xfd, 0x32, 0xa7, 0xc8, 0xa0, 0x5b, 0xbc, 0x90, 0xd3, 0x2c, 0x49 }; byte[] maskedDB = new byte[dbMask.Length]; for (int i = 0; i < dbMask.Length; i++) { maskedDB[i] = (byte)(DB[i] ^ dbMask[i]); } byte[] seedMask = pkcs1.GenerateMask(maskedDB, seed.Length); byte[] expectedSeedMask = { 0x2F, 0xC1, 0x35, 0x69, 0x61, 0x71, 0x74, 0x10, 0x72, 0x5F, 0xE6, 0x7, 0x2B, 0xB3, 0x4A, 0x1D, 0xEF, 0xC6, 0x48, 0x20 }; Assert.Equal(expectedSeedMask, seedMask); }
public static void GenerateMaskTest_SHA1() { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); byte[] seed = { 0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34, 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2, 0xf0, 0x6c, 0xb5, 0x8f }; int LengthDB = 107; byte[] expectedDBMask = { 0x06, 0xe1, 0xde, 0xb2, 0x36, 0x9a, 0xa5, 0xa5, 0xc7, 0x07, 0xd8, 0x2c, 0x8e, 0x4e, 0x93, 0x24, 0x8a, 0xc7, 0x83, 0xde, 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4e, 0xaf, 0xf4, 0x9c, 0x8c, 0x3b, 0x7c, 0xfc, 0x95, 0x1a, 0x51, 0xec, 0xd1, 0xdd, 0xe6, 0x12, 0x64 }; byte[] dbMask = pkcs1.GenerateMask(seed, LengthDB); Assert.Equal(expectedDBMask, dbMask); byte[] DB = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd4, 0x36, 0xe9, 0x95, 0x69, 0xfd, 0x32, 0xa7, 0xc8, 0xa0, 0x5b, 0xbc, 0x90, 0xd3, 0x2c, 0x49 }; byte[] maskedDB = new byte[dbMask.Length]; for (int i = 0; i < dbMask.Length; i++) { maskedDB[i] = (byte)(DB[i] ^ dbMask[i]); } byte[] seedMask = pkcs1.GenerateMask(maskedDB, seed.Length); byte[] expectedSeedMask = { 0x41, 0x87, 0x0b, 0x5a, 0xb0, 0x29, 0xe6, 0x57, 0xd9, 0x57, 0x50, 0xb5, 0x4c, 0x28, 0x3c, 0x08, 0x72, 0x5d, 0xbe, 0xa9 }; Assert.Equal(expectedSeedMask, seedMask); }
public static void NullSeedTest() { PKCS1MaskGenerationMethod pkcs1 = new PKCS1MaskGenerationMethod(); Assert.Throws <NullReferenceException>(() => pkcs1.GenerateMask(null, 10)); }