/// <summary> /// Method that implements EME-OAEP decoding /// </summary> /// <param name="EM"> /// Message to be decoded. An octet string of length k /// </param> /// <param name="label"> /// Optional label to be associated with the message; the /// default value for L, if L is not provided, is the empty string. /// </param> /// <param name="k"> /// Size of public key modulus in octets /// </param> /// <param name="hash"> /// Hash function (hLen denotes the length in octets of /// the hash function output) /// </param> /// <returns> /// Decoded message, octet string of length mLen /// </returns> /// <exception cref="DecryptionErrorException"> /// Method can throw exception /// </exception> public byte[] EME_OAEP_Decoding(byte[] EM, byte[] label, int k, HashAlgorithm hash) { int hLen = hash.HashSize / 8; byte[] lHash = hash.ComputeHash(label); if (EM[0] != 0x00) { throw new DecryptionErrorException("Decryption error!"); } byte[] maskedSeed = new byte[hLen]; byte[] maskedDB = new byte[k - hLen - 1]; System.Buffer.BlockCopy(EM, 1, maskedSeed, 0, maskedSeed.Length); System.Buffer.BlockCopy(EM, 1 + maskedSeed.Length, maskedDB, 0, maskedDB.Length); byte[] seedMask = mgf.MGF1(maskedDB, hLen, hash); byte[] seed = ByteArraysUtils.XorBytes(maskedSeed, seedMask); byte[] dbMask = mgf.MGF1(seed, k - hLen - 1, hash); byte[] DB = ByteArraysUtils.XorBytes(maskedDB, dbMask); byte[] lHash_dash = new byte[hLen]; System.Buffer.BlockCopy(DB, 0, lHash_dash, 0, hLen); if (!lHash.SequenceEqual(lHash_dash)) { throw new DecryptionErrorException("Decryption error!"); } int i = Array.FindIndex(DB, hLen, el => el == 0x01); if (i == -1) { throw new DecryptionErrorException("Decryption error!"); } byte[] M = new byte[DB.Length - 1 - i]; System.Buffer.BlockCopy(DB, i + 1, M, 0, M.Length); return(M); }
public void Concat() { byte[] arg1 = { 97, 29, 31, 55, 17, 0, 129 }; byte[] arg2 = { 12, 33, 14, 40, 199, 244, 87 }; byte[] expected = { 97, 29, 31, 55, 17, 0, 129, 12, 33, 14, 40, 199, 244, 87 }; CollectionAssert.AreEqual(expected, ByteArraysUtils.Concat(arg1, arg2)); }
public void GetSubArray() { byte[] arg1 = { 97, 29, 31, 55, 17, 0, 129 }; byte[] expected1 = { 31, 55, 17, 0 }; byte[] expected2 = { 97, 29 }; CollectionAssert.AreEqual(expected1, ByteArraysUtils.GetSubArray(arg1, 2, 4)); CollectionAssert.AreEqual(expected2, ByteArraysUtils.GetSubArray(arg1, 0, 2)); }
public void XorBytes() { byte[] arg1 = { 97, 29, 31, 55, 17, 0, 129 }; byte[] arg2 = { 12, 33, 14, 40, 199, 244, 87 }; byte[] xor = ByteArraysUtils.XorBytes(arg1, arg2); byte[] actual = ByteArraysUtils.XorBytes(xor, arg2); CollectionAssert.AreEqual(arg1, actual); }
/// <summary> /// Methos that implements EME-PKCS1 v1.5 encoding /// </summary> /// <param name="k">Size of public key modulus in octets</param> /// <param name="M">Message to be encoded, an octet string</param> /// <returns>Encoded message, and octet string of length k</returns> public byte[] EME_PKCS1_Encoding(int k, byte[] M) { byte[] PS = ByteArraysUtils.GetRandomNonZeroOctets(RNGCryptoServiceProvider.Create(), k - M.Length - 3); byte[] EM = new byte[k]; System.Buffer.SetByte(EM, 0, (byte)0x00); System.Buffer.SetByte(EM, 1, (byte)0x02); System.Buffer.BlockCopy(PS, 0, EM, 2, PS.Length); System.Buffer.SetByte(EM, PS.Length + 2, (byte)0x00); System.Buffer.BlockCopy(M, 0, EM, PS.Length + 3, M.Length); return(EM); }
/// <summary> /// Method that implements EME-OAEP encoding. /// </summary> /// <param name="message"> /// Message to be encoded, an octet string of length mLen, where mLen <= k - 2hLen - 2 /// </param> /// <param name="label"> /// Optional label to be associated with the message; the /// default value for L, if L is not provided, is the empty string. /// </param> /// <param name="k"> /// Size of public key modulus in octets /// </param> /// <param name="hash"> /// Hash function (hLen denotes the length in octets of /// the hash function output) /// </param> /// <returns> /// Encoded message of k length /// </returns> public byte[] EME_OAEP_Encoding(byte[] message, byte[] label, int k, HashAlgorithm hash) { int hLen = hash.HashSize / 8; byte[] lHash = hash.ComputeHash(label); byte[] PS = new byte[k - message.Length - 2 * hLen - 2]; byte[] DB = new byte[k - hLen - 1]; System.Buffer.BlockCopy(lHash, 0, DB, 0, lHash.Length); System.Buffer.BlockCopy(PS, 0, DB, lHash.Length, PS.Length); DB[lHash.Length + PS.Length] = 0x01; System.Buffer.BlockCopy(message, 0, DB, lHash.Length + PS.Length + 1, message.Length); byte[] seed = ByteArraysUtils.GetRandomOctets(RNGCryptoServiceProvider.Create(), hLen); byte[] dbMask = mgf.MGF1(seed, k - hLen - 1, hash); byte[] maskedDB = ByteArraysUtils.XorBytes(DB, dbMask); byte[] seedMask = mgf.MGF1(maskedDB, hLen, hash); byte[] maskedSeed = ByteArraysUtils.XorBytes(seed, seedMask); byte[] EM = new byte[k]; System.Buffer.SetByte(EM, 0, 0x00); System.Buffer.BlockCopy(maskedSeed, 0, EM, 1, maskedSeed.Length); System.Buffer.BlockCopy(maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length); return(EM); }
public byte[] EMSA_PSS_Encoding(byte[] M, int k, int sLen) { int hLen = hash.HashSize; int emLen = k / 8; var mHash = hash.ComputeHash(M); if (emLen < hLen + sLen + 2) { throw new EncodingException(); } byte[] salt = ByteArraysUtils.GetRandomOctets(RNGCryptoServiceProvider.Create(), sLen); var M_dash = ByteArraysUtils.Concat(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, ByteArraysUtils.Concat(mHash, salt)); var H = hash.ComputeHash(M_dash); var PS = new byte[emLen - sLen - hLen - 2]; var DB = ByteArraysUtils.Concat(ByteArraysUtils.Concat(PS, new byte[] { 0x01 }), salt); var dbMask = mgf.MGF1(H, emLen - hLen - 1, hash); var maskedDB = ByteArraysUtils.XorBytes(DB, dbMask); maskedDB[0] &= (byte)(0xFF >> (8 * emLen - k)); var EM = ByteArraysUtils.Concat(ByteArraysUtils.Concat(maskedDB, H), new byte[] { 0xbc }); return(EM); }