示例#1
0
        public static byte[] PBKDF2(byte[] password, byte[] salt, int iterCount, int cOctets, IDigest digest)
        {
            //  PRF = HMAC- SHA (256, 384, 512)
            //  P = passsword
            //  S = salt
            //  c = iteration count
            //  dkLen = cbits in octets

            //  l = CIEL(dkLen / hLen)
            //  r = dkLen - (l - 1)*hLen

            // T_n = F ( P, S, c, n)  (iterate n=1 to l)

            // F ( P, S, c, i) = U_1 ^ U_2 ^ ... ^ U_c

            // U_1 = PRF( P, S || INT (i))
            // U_2 = PRF( P, U_1 )
            // U_c = PRF( P, U_{c-1})
            //  INT = int32- big-ending

            HMac hmac           = new HMac(digest);
            ICipherParameters k = new KeyParameter(password);

            hmac.Init(k);
            int hLen = hmac.GetMacSize();
            int l    = (cOctets + hLen - 1) / hLen;

            byte[] rgbStart = new byte[salt.Length + 4];
            Array.Copy(salt, 0, rgbStart, 0, salt.Length);
            byte[] rgbOutput = new byte[l * hLen];

            for (int i = 1; i <= l; i++)
            {
                byte[] rgbT = new byte[hLen];
                byte[] rgbH = new byte[hLen];

                hmac.Reset();
                rgbStart[rgbStart.Length - 1] = (byte)i;
                hmac.BlockUpdate(rgbStart, 0, rgbStart.Length);
                hmac.DoFinal(rgbH, 0);
                Array.Copy(rgbH, rgbT, rgbH.Length);

                for (int j = 1; j < iterCount; j++)
                {
                    hmac.Reset();
                    hmac.BlockUpdate(rgbH, 0, rgbH.Length);
                    hmac.DoFinal(rgbH, 0);
                    for (int k1 = 0; k1 < rgbH.Length; k1++)
                    {
                        rgbT[k1] ^= rgbH[k1];
                    }
                }

                Array.Copy(rgbT, hLen * (i - 1), rgbOutput, 0, rgbT.Length);
            }

            byte[] rgbOut = new Byte[cOctets];
            Array.Copy(rgbOutput, rgbOut, cOctets);
            return(rgbOut);
        }
        private Byte[] P_hash(Byte[] secret, Byte[] seed, Int32 size, IDigest digest)
        {
            var needed = size;

            var md  = new HMac(digest);
            var key = new KeyParameter(secret);

            md.Init(key);

            // A_0 is initialized with seed
            var a0 = new Byte[seed.Length];

            Array.Copy(seed, 0, a0, 0, a0.Length);

            // A_i is HMAC of previous A
            var aI = new Byte[md.GetMacSize()];

            md.BlockUpdate(a0, 0, a0.Length);
            md.DoFinal(aI, 0);
            md.Reset();
            var ret = new Byte[needed];

            var outBuff = new Byte[md.GetMacSize()];

            while (needed > 0)
            {
                md.Init(key);
                // Add to return value
                md.BlockUpdate(aI, 0, aI.Length);
                md.BlockUpdate(seed, 0, seed.Length);
                md.DoFinal(outBuff, 0);
                md.Reset();

                var lenToCopy = needed < md.GetMacSize()? needed : md.GetMacSize();
                Array.Copy(outBuff, 0, ret, size - needed, lenToCopy);

                // Update new A
                md.Init(key);
                md.BlockUpdate(aI, 0, aI.Length);
                md.DoFinal(aI, 0);
                md.Reset();

                // Update needed field
                needed -= md.GetMacSize();
            }

            return(ret);
        }
示例#3
0
        private void ComputeNextBlock(HMac hash)
        {
            BigEndian.CopyBytes(m_blockNumber, m_saltWithBlock, m_saltWithBlock.Length - 4);

            byte[] final = new byte[hash.GetMacSize()];
            byte[] tmp   = new byte[hash.GetMacSize()];

            //InitialPass: U1 = PRF(Password, Salt || INT_32_BE(i))
            hash.Reset();
            hash.BlockUpdate(m_saltWithBlock, 0, m_saltWithBlock.Length);
            hash.DoFinal(final, 0);

            final.CopyTo(tmp, 0);

            for (int iteration = 1; iteration < m_iterations; iteration++)
            {
                //U2 = PRF(Password, U1)
                //hash.Reset();
                hash.BlockUpdate(tmp, 0, tmp.Length);
                hash.DoFinal(tmp, 0);
                for (int x = 0; x < tmp.Length; x++)
                {
                    final[x] ^= tmp[x];
                }
            }

            m_blockNumber++;
            foreach (var b in final)
            {
                m_results.Enqueue(b);
            }
        }
示例#4
0
文件: TlsMac.cs 项目: EnergonV/BestCS
        public virtual byte[] CalculateMacConstantTime(ContentType type, byte[] message, int offset, int len,
                                                       int fullLength, byte[] dummyData)
        {
            // Actual MAC only calculated on 'len' bytes
            byte[] result = CalculateMac(type, message, offset, len);

            //bool isTls = context.ServerVersion.FullVersion >= ProtocolVersion.TLSv10.FullVersion;
            bool isTls = true;

            // ...but ensure a constant number of complete digest blocks are processed (per 'fullLength')
            if (isTls)
            {
                // TODO Currently all TLS digests use a block size of 64, a suffix (length field) of 8, and padding (1+)
                int db = 64, ds = 8;

                int L1 = 13 + fullLength;
                int L2 = 13 + len;

                // How many extra full blocks do we need to calculate?
                int extra = ((L1 + ds) / db) - ((L2 + ds) / db);

                while (--extra >= 0)
                {
                    mac.BlockUpdate(dummyData, 0, db);
                }

                // One more byte in case the implementation is "lazy" about processing blocks
                mac.Update(dummyData[0]);
                mac.Reset();
            }

            return(result);
        }
示例#5
0
 /**
  * Calculate the mac for some given data.
  * <p/>
  * TlsMac will keep track of the sequence number internally.
  *
  * @param type    The message type of the message.
  * @param message A byte-buffer containing the message.
  * @param offset  The number of bytes to skip, before the message starts.
  * @param len     The length of the message.
  * @return A new byte-buffer containing the mac value.
  */
 internal byte[] CalculateMac(
     short type,
     byte[]  message,
     int offset,
     int len)
 {
     try
     {
         MemoryStream bosMac = new MemoryStream(13 + len);
         TlsUtilities.WriteUint64(seqNo++, bosMac);
         TlsUtilities.WriteUint8(type, bosMac);
         TlsUtilities.WriteVersion(bosMac);
         TlsUtilities.WriteUint16(len, bosMac);
         bosMac.Write(message, offset, len);
         byte[] macData = bosMac.ToArray();
         mac.BlockUpdate(macData, 0, macData.Length);
         byte[] result = new byte[mac.GetMacSize()];
         mac.DoFinal(result, 0);
         mac.Reset();
         return(result);
     }
     catch (IOException)
     {
         // This should never happen
         throw new InvalidOperationException("Internal error during mac calculation");
     }
 }
示例#6
0
        byte[] HashFinal()
        {
            var value = new byte[hash.GetMacSize()];

            hash.DoFinal(value, 0);
            hash.Reset();

            return(value);
        }
        public bool Verify(byte[] data, string tag)
        {
            byte[] output = new byte[_hmac.GetMacSize()];
            _hmac.Reset();
            _hmac.BlockUpdate(data, 0, data.Length);
            _hmac.DoFinal(output, 0);

            return(output.SequenceEqual(Base64.Decode(tag)));
        }
示例#8
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            Finish();

            if (disposing)
            {
                _hmacAlg.Reset();
            }
            _hmacAlg = null;

            base.Dispose(disposing);
        }
示例#9
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            Finish();

            if (disposing)
            {
                _hmacAlg.Reset();
                _hashValue.Clear();
                _fullHashValue.Clear();
            }
            _hmacAlg = null;

            base.Dispose(disposing);
        }
示例#10
0
        public virtual ITestResult Perform()
        {
            HMac hmac = new HMac(new Sha384Digest());

            byte[] resBuf = new byte[hmac.GetMacSize()];

            for (int i = 0; i < messages.Length; i++)
            {
                byte[] m = Encoding.ASCII.GetBytes(messages[i]);
                if (messages[i].StartsWith("0x"))
                {
                    m = Hex.Decode(messages[i].Substring(2));
                }
                hmac.Init(new KeyParameter(Hex.Decode(keys[i])));
                hmac.BlockUpdate(m, 0, m.Length);
                hmac.DoFinal(resBuf, 0);

                if (!Arrays.AreEqual(resBuf, Hex.Decode(digests[i])))
                {
                    return(new SimpleTestResult(false, Name + ": Vector " + i + " failed"));
                }
            }

            //
            // test reset
            //
            int vector = 0; // vector used for test

            byte[] m2 = Encoding.ASCII.GetBytes(messages[vector]);
            if (messages[vector].StartsWith("0x"))
            {
                m2 = Hex.Decode(messages[vector].Substring(2));
            }
            hmac.Init(new KeyParameter(Hex.Decode(keys[vector])));
            hmac.BlockUpdate(m2, 0, m2.Length);
            hmac.DoFinal(resBuf, 0);
            hmac.Reset();
            hmac.BlockUpdate(m2, 0, m2.Length);
            hmac.DoFinal(resBuf, 0);

            if (!Arrays.AreEqual(resBuf, Hex.Decode(digests[vector])))
            {
                return(new SimpleTestResult(false, Name + "Reset with vector " + vector + " failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
示例#11
0
        private static byte[] HKDF(byte[] secret, byte[] salt, byte[] info, int cbit, IDigest digest)
        {
            //  Now start doing HKDF
            //  Perform the Extract phase
            HMac mac = new HMac(digest);

            int hashLength = digest.GetDigestSize();
            int c          = ((cbit + 7) / 8 + hashLength - 1) / hashLength;

            if (salt == null)
            {
                salt = new byte[0];
            }
            KeyParameter key = new KeyParameter(salt);

            mac.Init(key);
            mac.BlockUpdate(secret, 0, secret.Length);

            byte[] rgbExtract = new byte[hashLength];
            mac.DoFinal(rgbExtract, 0);


            //  Now do the Expand Phase

            byte[] rgbOut = new byte[cbit / 8];
            byte[] rgbT   = new byte[hashLength * c];
            mac = new HMac(digest);
            key = new KeyParameter(rgbExtract);
            mac.Init(key);
            byte[] rgbLast  = new byte[0];
            byte[] rgbHash2 = new byte[hashLength];

            for (int i = 0; i < c; i++)
            {
                mac.Reset();
                mac.BlockUpdate(rgbLast, 0, rgbLast.Length);
                mac.BlockUpdate(info, 0, info.Length);
                mac.Update((byte)(i + 1));

                rgbLast = rgbHash2;
                mac.DoFinal(rgbLast, 0);
                Array.Copy(rgbLast, 0, rgbT, i * hashLength, hashLength);
            }

            Array.Copy(rgbT, 0, rgbOut, 0, cbit / 8);
            return(rgbOut);
        }
示例#12
0
        public override void PerformTest()
        {
            HMac hmac = new HMac(new NonMemoableDigest(new Sha1Digest()));

            byte[] resBuf = new byte[hmac.GetMacSize()];

            for (int i = 0; i < messages.Length; i++)
            {
                byte[] m = Strings.ToByteArray(messages[i]);
                if (messages[i].StartsWith("0x"))
                {
                    m = Hex.Decode(messages[i].Substring(2));
                }
                hmac.Init(new KeyParameter(Hex.Decode(keys[i])));
                hmac.BlockUpdate(m, 0, m.Length);
                hmac.DoFinal(resBuf, 0);

                if (!Arrays.AreEqual(resBuf, Hex.Decode(digests[i])))
                {
                    Fail(Name + ": Vector " + i + " failed");
                }
            }

            //
            // test reset
            //
            {
                int    vector = 0; // vector used for test
                byte[] m      = Strings.ToByteArray(messages[vector]);
                if (messages[vector].StartsWith("0x"))
                {
                    m = Hex.Decode(messages[vector].Substring(2));
                }
                hmac.Init(new KeyParameter(Hex.Decode(keys[vector])));
                hmac.BlockUpdate(m, 0, m.Length);
                hmac.DoFinal(resBuf, 0);
                hmac.Reset();
                hmac.BlockUpdate(m, 0, m.Length);
                hmac.DoFinal(resBuf, 0);

                if (!Arrays.AreEqual(resBuf, Hex.Decode(digests[vector])))
                {
                    Fail(Name + ": Reset with vector " + vector + " failed");
                }
            }
        }
示例#13
0
 public void Initialize()
 {
     Hmac.Reset();
 }
示例#14
0
        /// <summary>
        ///   Create two streched keys from the shared secret.
        /// </summary>
        /// <remarks>
        ///   The is no spec for this.  Copied https://github.com/libp2p/go-libp2p-crypto/blob/0f79fbebcb64f746a636aba79ece0635ec5919e9/key.go#L183
        /// </remarks>
        public static void Generate(string cipherName,
                                    string hashName,
                                    byte[] secret,
                                    out StretchedKey k1,
                                    out StretchedKey k2)
        {
            int cipherKeySize;
            int ivSize;

            switch (cipherName)
            {
            case "AES-128":
                ivSize        = 16;
                cipherKeySize = 16;
                break;

            case "AES-256":
                ivSize        = 16;
                cipherKeySize = 32;
                break;

            case "Blowfish":
                ivSize        = 8;
                cipherKeySize = 32;
                break;

            default:
                throw new NotSupportedException($"Cipher '{cipherName}' is not supported.");
            }

            var hmacKeySize = 20;
            var need        = 2 * (ivSize + cipherKeySize + hmacKeySize);

            var hmac = new HMac(DigestUtilities.GetDigest(hashName));
            var kp   = new KeyParameter(secret);
            var seed = Encoding.ASCII.GetBytes("key expansion");

            hmac.Init(kp);
            var a = new byte[hmac.GetMacSize()];
            var b = new byte[hmac.GetMacSize()];

            hmac.BlockUpdate(seed, 0, seed.Length);
            hmac.DoFinal(a, 0);

            var j      = 0;
            var result = new byte[need];

            while (j < need)
            {
                hmac.Reset();
                hmac.BlockUpdate(a, 0, a.Length);
                hmac.BlockUpdate(seed, 0, seed.Length);
                hmac.DoFinal(b, 0);

                var todo = b.Length;
                if (j + todo > need)
                {
                    todo = need - j;
                }
                Buffer.BlockCopy(b, 0, result, j, todo);
                j += todo;

                hmac.Reset();
                hmac.BlockUpdate(a, 0, a.Length);
                hmac.DoFinal(a, 0);
            }

            var half = need / 2;

            k1 = new StretchedKey
            {
                Iv        = new byte[ivSize],
                CipherKey = new byte[cipherKeySize],
                MacKey    = new byte[hmacKeySize]
            };
            Buffer.BlockCopy(result, 0, k1.Iv, 0, ivSize);
            Buffer.BlockCopy(result, ivSize, k1.CipherKey, 0, cipherKeySize);
            Buffer.BlockCopy(result, ivSize + cipherKeySize, k1.MacKey, 0, hmacKeySize);

            k2 = new StretchedKey
            {
                Iv        = new byte[ivSize],
                CipherKey = new byte[cipherKeySize],
                MacKey    = new byte[hmacKeySize]
            };
            Buffer.BlockCopy(result, half, k2.Iv, 0, ivSize);
            Buffer.BlockCopy(result, half + ivSize, k2.CipherKey, 0, cipherKeySize);
            Buffer.BlockCopy(result, half + ivSize + cipherKeySize, k2.MacKey, 0, hmacKeySize);
        }
示例#15
0
        public static Tuple <StretchedKeys, StretchedKeys> Generate(string cipherType, string hashType, byte[] secret)
        {
            var cipherKeySize = 0;
            var ivSize        = 0;

            switch (cipherType)
            {
            case "AES-128":
                ivSize        = 16;
                cipherKeySize = 16;
                break;

            case "AES-256":
                ivSize        = 16;
                cipherKeySize = 32;
                break;

            case "Blowfish":
                ivSize        = 8;
                cipherKeySize = 32;
                break;
            }
            var hmacKeySize = 20;
            var seed        = Encoding.UTF8.GetBytes("key expansion");
            var result      = new byte[2 * (ivSize + cipherKeySize + hmacKeySize)];
            var m           = new HMac(DigestUtilities.GetDigest(hashType));

            m.Init(new KeyParameter(secret));
            m.BlockUpdate(seed, 0, seed.Length);
            var a = new byte[m.GetMacSize()];

            m.DoFinal(a, 0);

            var j = 0;

            while (j < result.Length)
            {
                m.Reset();
                m.BlockUpdate(a, 0, a.Length);
                m.BlockUpdate(seed, 0, seed.Length);
                var b = new byte[m.GetMacSize()];
                m.DoFinal(b, 0);

                var todo = b.Length;

                if (j + todo > result.Length)
                {
                    todo = result.Length - j;
                }

                Buffer.BlockCopy(b, 0, result, j, todo);

                j += todo;

                m.Reset();
                m.BlockUpdate(a, 0, a.Length);
                m.DoFinal(a, 0);
            }

            var half = result.Length / 2;
            var r1   = result.Slice(0, half);
            var r2   = result.Slice(half);

            var k1 = new StretchedKeys
            {
                IV        = r1.Slice(0, ivSize),
                CipherKey = r1.Slice(ivSize, cipherKeySize),
                MacKey    = r1.Slice(ivSize + cipherKeySize)
            };

            var k2 = new StretchedKeys
            {
                IV        = r2.Slice(0, ivSize),
                CipherKey = r2.Slice(ivSize, cipherKeySize),
                MacKey    = r2.Slice(ivSize + cipherKeySize)
            };

            return(Tuple.Create(k1, k2));
        }