상속: IMac
예제 #1
0
        public virtual void Init(ICipherParameters parameters)
        {
            this.digest.Reset();
            byte[] key = ((KeyParameter)parameters).GetKey();
            int    num = key.Length;

            if (num > this.blockLength)
            {
                this.digest.BlockUpdate(key, 0, num);
                this.digest.DoFinal(this.inputPad, 0);
                num = this.digestSize;
            }
            else
            {
                Array.Copy(key, 0, this.inputPad, 0, num);
            }
            Array.Clear(this.inputPad, num, this.blockLength - num);
            Array.Copy(this.inputPad, 0, this.outputBuf, 0, this.blockLength);
            HMac.XorPad(this.inputPad, this.blockLength, 54);
            HMac.XorPad(this.outputBuf, this.blockLength, 92);
            if (this.digest is IMemoable)
            {
                this.opadState = ((IMemoable)this.digest).Copy();
                ((IDigest)this.opadState).BlockUpdate(this.outputBuf, 0, this.blockLength);
            }
            this.digest.BlockUpdate(this.inputPad, 0, this.inputPad.Length);
            if (this.digest is IMemoable)
            {
                this.ipadState = ((IMemoable)this.digest).Copy();
            }
        }
예제 #2
0
 public static string CalculateRequestHash(HMac mac, byte[] data)
 {
     mac.Init(new KeyParameter(Encoding.UTF8.GetBytes(PagarMeService.DefaultApiKey)));
     mac.BlockUpdate(data, 0, data.Length);
     byte[] result = new byte[mac.GetMacSize()];
     mac.DoFinal(result, 0);
     string hex = BitConverter.ToString(result).Replace("-", "").ToLower();
     return hex;
 }
예제 #3
0
 public static byte[] Compute(IDigest hash, byte[] key, byte[] data, int position, int length)
 {
     data.ValidateParameters(position, length);
     var hmac = new HMac(hash);
     hmac.Init(new KeyParameter(key));
     var result = new byte[hmac.GetMacSize()];
     hmac.BlockUpdate(data, position, length);
     hmac.DoFinal(result, 0);
     return result;
 }
        /**
         * Create a {@link SimulatedTlsSRPIdentityManager} that implements the algorithm from RFC 5054 2.5.1.3
         *
         * @param group the {@link SRP6GroupParameters} defining the group that SRP is operating in
         * @param seedKey the secret "seed key" referred to in RFC 5054 2.5.1.3
         * @return an instance of {@link SimulatedTlsSRPIdentityManager}
         */
        public static SimulatedTlsSrpIdentityManager GetRfc5054Default(Srp6GroupParameters group, byte[] seedKey)
        {
            Srp6VerifierGenerator verifierGenerator = new Srp6VerifierGenerator();
            verifierGenerator.Init(group, TlsUtilities.CreateHash(HashAlgorithm.sha1));

            HMac mac = new HMac(TlsUtilities.CreateHash(HashAlgorithm.sha1));
            mac.Init(new KeyParameter(seedKey));

            return new SimulatedTlsSrpIdentityManager(group, verifierGenerator, mac);
        }
예제 #5
0
		/**
		* Generate a new instance of an TlsMac.
		*
		* @param digest    The digest to use.
		* @param key_block A byte-array where the key for this mac is located.
		* @param offset    The number of bytes to skip, before the key starts in the buffer.
		* @param len       The length of the key.
		*/
		internal TlsMac(
			IDigest	digest,
			byte[]	key_block,
			int		offset,
			int		len)
		{
			this.mac = new HMac(digest);
			KeyParameter param = new KeyParameter(key_block, offset, len);
			this.mac.Init(param);
			this.seqNo = 0;
		}
예제 #6
0
        public void CheckFingerprint()
        {
            var expectedSignature = "fd29daad6c47ff78c1604395320b60bac87830cb";
            var expectedResult    = "sha1=" + expectedSignature;
            var bizareDigest      = "lol=" + expectedSignature;
            var inputData         = "{\"sample\":\"payload\",\"value\":true}";

            var hmac = new HMac( new Org.BouncyCastle.Crypto.Digests.Sha1Digest() );
            Assert.AreEqual( PagarMe.Utils.CalculateRequestHash(hmac, inputData), expectedSignature );

            Assert.IsTrue(  PagarMe.Utils.ValidateRequestSignature( inputData, expectedResult    ) );
            Assert.IsFalse( PagarMe.Utils.ValidateRequestSignature( inputData, bizareDigest      ) );
            Assert.IsFalse( PagarMe.Utils.ValidateRequestSignature( inputData, expectedSignature ) );
        }
예제 #7
0
        /**
        * Generate a new instance of an TlsMac.
        *
        * @param digest    The digest to use.
        * @param key_block A byte-array where the key for this mac is located.
        * @param offset    The number of bytes to skip, before the key starts in the buffer.
        * @param len       The length of the key.
        */
        public TlsMac(
            IDigest	digest,
            byte[]	key_block,
            int		offset,
            int		len)
        {
            this.seqNo = 0;

            KeyParameter param = new KeyParameter(key_block, offset, len);

            this.secret = Arrays.Clone(param.GetKey());

            this.mac = new HMac(digest);
            this.mac.Init(param);
        }
예제 #8
0
        /// <summary>
        /// Hash+Mac string data based on the supported digest types, also, deviates the key data based on supported divination types.
        /// </summary>
        /// <param name="data">Data of any encoding type</param>
        /// <param name="key">Hash password. Will be deviated using the supplied divination type.</param>
        /// <returns>byte[]</returns>
        public static byte[] ToHmac(this string data, string key)
        {
            var dataBytes = new UTF8Encoding().GetBytes(data);
            var derivedKey = new UTF8Encoding().GetBytes(key);
            var digest = new HMac(new Sha256Digest());

            digest.Init(new KeyParameter(derivedKey));
            digest.BlockUpdate(dataBytes, 0, dataBytes.Length);

            var output = new byte[digest.GetMacSize()];
            digest.DoFinal(output, 0);
            digest.Reset();

            return output;
        }
예제 #9
0
        /// <summary>
        /// Hash+Mac string data based on the supported digest types, also, deviates the key data based on supported divination types.
        /// </summary>
        /// <param name="data">Data of any encoding type</param>
        /// <param name="key">Hash password. Will be deviated using the supplied divination type.</param>
        /// <param name="salt">Optional, supplied 8 byte salt, one will be auto-generated if not supplied</param>
        /// <returns>SaltedData</returns>
        public static SaltedData ToHmac(this string data, string key, byte[] salt)
        {
            var salting = salt ?? 16.ToRandomBytes();
            var dataBytes = new UTF8Encoding().GetBytes(data);
            var derivedKey = key.ToKeyDevination(salting).Data;
            var digest = new HMac(new Sha256Digest());

            digest.Init(new KeyParameter(derivedKey));
            digest.BlockUpdate(dataBytes, 0, dataBytes.Length);

            var output = new byte[digest.GetMacSize()];
            digest.DoFinal(output, 0);
            digest.Reset();

            return new SaltedData() {Data = output, Salt = salting};
        }
예제 #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");
        }
        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");
                }
            }
        }
        private void EncryptData(byte[] dataToEncrypt, string password)
        {
            // Generate the encryption key
            var hash = PasswordHash.CreateHash(password, 1, "");
            
            // Generate the authentication key
            var authKeyHash = PasswordHash.CreateHash(password, 2, "");
            var authKey = Convert.FromBase64String(authKeyHash);

            _encryptedData = new EncryptedData(dataToEncrypt, Convert.FromBase64String(hash)).ToBytes();
            
            var hmac = new HMac(new Sha256Digest());
            var mac = new byte[hmac.GetMacSize()];
            hmac.Init(new KeyParameter(authKey));
            hmac.BlockUpdate(_encryptedData, 0, _encryptedData.Length);
            hmac.DoFinal(mac, 0);
            _encryptedDataHmac = mac;
        }
		private string GetHmacSha256(string stringToSign, string secretKey)
		{
			var key = Encoding.UTF8.GetBytes(secretKey);
			var data = Encoding.UTF8.GetBytes(stringToSign);
			var hash = new Sha256Digest();

			HMac hmac = new HMac(hash);

			hmac.Init(new KeyParameter(key, 0, key.Length));

			hmac.BlockUpdate(data, 0, data.Length);

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

			int nRet = hmac.DoFinal(abyDigest, 0);

			return System.Convert.ToBase64String(abyDigest); ;
		}
예제 #14
0
        public async static Task<string> GetStreamUrlAsync(object parameter)
        {
            var SongSelected = (Song)parameter;
            byte[] s1 = Convert.FromBase64String("VzeC4H4h+T2f0VI180nVX8x+Mb5HiTtGnKgH52Otj8ZCGDz9jRW" +
                                 "yHb6QXK0JskSiOgzQfwTY5xgLLSdUSreaLVMsVVWfxfa8Rw==");
            byte[] s2 = Convert.FromBase64String("ZAPnhUkYwQ6y5DdQxWThbvhJHN8msQ1rqJw0ggKdufQjelrKuiG" +
                                 "GJI30aswkgCWTDyHkTGK9ynlqTkJ5L4CiGGUabGeo8M6JTQ==");
            StringBuilder byteString = new StringBuilder();

            for (int i = 0; i < s1.Length; i++)
            {
                byteString.Append((char)(s1[i] ^ s2[i]));
            }
            byte[] key = Encoding.ASCII.GetBytes(byteString.ToString());

            HMac mac = new HMac(new Sha1Digest());

            KeyParameter param = new KeyParameter(key);
            byte[] output = new byte[mac.GetMacSize()];
            mac.Init(param);
            parameter = SongSelected.Id;
            string CurrentTimestamp = ((long)((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds * 1000)).ToString();
            Encoding enc = new UTF8Encoding();
            var salt = enc.GetBytes(CurrentTimestamp);
            var songId = enc.GetBytes((string)parameter);

            mac.BlockUpdate(songId, 0, songId.Length);
            mac.BlockUpdate(enc.GetBytes(CurrentTimestamp), 0, salt.Length);
            mac.DoFinal(output, 0);

            var sig = System.Convert.ToBase64String(output).TrimEnd(new char[] { '=' }).Replace('+', '-').Replace('/', '_');

            HttpRequestMessage message = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri("https://android.clients.google.com/music/mplay?opt=hi&net=mob&pt=e&slt=" + CurrentTimestamp + "&sig=" + sig + "&mjck=" + SongSelected.Id, UriKind.Absolute)
            };

            var songString = await HttpCall.MakeGetCallAsync(message);
            string url = songString.Headers.Location.ToString();
            return url;
        }
예제 #15
0
        public static string Generate()
        {
            byte[] guid = Guid.NewGuid().ToByteArray();

            var hMac = new HMac(new Sha256Digest());
            int hmacSize = hMac.GetMacSize();
            int lengthMultipler = (KEY_LENGTH + hmacSize - 1) / hmacSize;

            byte[] block = new byte[4];
            byte[] outBytes = new byte[lengthMultipler * hmacSize];

            for (int index = 1; index <= lengthMultipler; index++)
            {
                IntToOctet(index, block);
                HashFunc(hMac, guid, block, outBytes, (index - 1) * hmacSize);
            }

            byte[] keyBytes = new byte[KEY_LENGTH];
            Buffer.BlockCopy(outBytes, 0, keyBytes, 0, KEY_LENGTH);

            return new Guid(keyBytes).ToString(); // for friendly formatting
        }
예제 #16
0
        public static string HashSomething(string password, string something)
        {
            var dig = new Sha256Digest();
            byte[] bpassword = Encoding.UTF8.GetBytes(password);
            dig.BlockUpdate(bpassword, 0, bpassword.Length);
            var key = new byte[dig.GetDigestSize()];
            dig.DoFinal(key, 0);

            var hmac = new HMac(new Sha256Digest());
            hmac.Init(new KeyParameter(key));
            byte[] input = Encoding.UTF8.GetBytes(something);
            hmac.BlockUpdate(input, 0, input.Length);
            var output = new byte[hmac.GetMacSize()];
            hmac.DoFinal(output, 0);

            var sb = new StringBuilder(output.Length*2);
            foreach (byte b in output)
            {
                sb.AppendFormat("{0:x2}", b);
            }
            return sb.ToString();
        }
예제 #17
0
        private static void HashFunc(HMac hMac, byte[] unique, byte[] block, byte[] outBytes, int outOff)
        {
            byte[] state = new byte[hMac.GetMacSize()];

            var cipherParam = new KeyParameter(unique);

            hMac.Init(cipherParam);
            hMac.BlockUpdate(_Salt, 0, _Salt.Length);
            hMac.BlockUpdate(block, 0, block.Length);
            hMac.DoFinal(state, 0);

            Array.Copy(state, 0, outBytes, outOff, state.Length);
            for (int iteration = 1; iteration < ITERATION_COUNT; iteration++)
            {
                hMac.Init(cipherParam);
                hMac.BlockUpdate(state, 0, state.Length);
                hMac.DoFinal(state, 0);

                for (int stateIndex = 0; stateIndex < state.Length; stateIndex++)
                {
                    outBytes[outOff + stateIndex] ^= state[stateIndex];
                }
            }
        }
예제 #18
0
		public ITestResult Perform()
        {
            HMac hmac = new HMac(new RipeMD160Digest());
            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");
                }
            }

            return new SimpleTestResult(true, Name + ": Okay");
        }
예제 #19
0
		public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

			var agreedValue = ECDHAgree (ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey);

			// Hash the agreed key
			var hashedValue = Helpers.SHA256Hash (Helpers.ToByteArray(agreedValue, 20));

			// Fold to get the actual key for AES
			byte[] aesKey = Helpers.Fold (hashedValue);
			Random rnd = new Random ();

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			rnd.NextBytes (aesIV);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (aesKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Construct the packet minus the hmac
			Packet outPacket = new Packet ();
			outPacket.Body = new byte[29 + encryptedInner.Length];
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (aesIV, 0, outPacket.Body, 21, 4);
			Buffer.BlockCopy (encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length);

			// ECDH for the hmac key using 
			var idAgreedValue = ECDHAgree (ri.RemotePublicKey, Key.PrivateKey);

			// Mash on the IV for the compound key
			byte[] macKey = new byte[24];
			byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20);
			Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length);
			Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4);

			// Actually hmac all the data now
			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (macKey, 0, 24));
			hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// Fold it up, shove it in and we're done
			var foldedMac = Helpers.Fold(mac, 3);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length);

			return outPacket;
		}
예제 #20
0
		private static void hmac_hash(IDigest digest, byte[] secret, byte[] seed, byte[] output)
		{
			HMac mac = new HMac(digest);
			KeyParameter param = new KeyParameter(secret);
			byte[] a = seed;
			int size = digest.GetDigestSize();
			int iterations = (output.Length + size - 1) / size;
			byte[] buf = new byte[mac.GetMacSize()];
			byte[] buf2 = new byte[mac.GetMacSize()];
			for (int i = 0; i < iterations; i++)
			{
				mac.Init(param);
				mac.BlockUpdate(a, 0, a.Length);
				mac.DoFinal(buf, 0);
				a = buf;
				mac.Init(param);
				mac.BlockUpdate(a, 0, a.Length);
				mac.BlockUpdate(seed, 0, seed.Length);
				mac.DoFinal(buf2, 0);
				Array.Copy(buf2, 0, output, (size * i), System.Math.Min(size, output.Length - (size * i)));
			}
		}
예제 #21
0
 /**
  * Base constructor.
  *
  * @param digest digest to build the HMAC on.
  */
 public HMacDsaKCalculator(IDigest digest)
 {
     this.hMac = new HMac(digest);
     this.V = new byte[hMac.GetMacSize()];
     this.K = new byte[hMac.GetMacSize()];
 }
예제 #22
0
		/// <summary>
		/// Calculate the current code for the authenticator.
		/// </summary>
		/// <param name="resyncTime">flag to resync time</param>
		/// <returns>authenticator code</returns>
		protected override string CalculateCode(bool resyncTime = false, long interval = -1)
		{
			// sync time if required
			if (resyncTime == true || ServerTimeDiff == 0)
			{
				if (interval > 0)
				{
					ServerTimeDiff = (interval * 30000L) - CurrentTime;
				}
				else
				{
					Sync();
				}
			}

			HMac hmac = new HMac(new Sha1Digest());
			hmac.Init(new KeyParameter(SecretKey));

			byte[] codeIntervalArray = BitConverter.GetBytes(CodeInterval);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(codeIntervalArray);
			}
			hmac.BlockUpdate(codeIntervalArray, 0, codeIntervalArray.Length);

			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// the last 4 bits of the mac say where the code starts (e.g. if last 4 bit are 1100, we start at byte 12)
			int start = mac[19] & 0x0f;

			// extract those 4 bytes
			byte[] bytes = new byte[4];
			Array.Copy(mac, start, bytes, 0, 4);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(bytes);
			}
			uint fullcode = BitConverter.ToUInt32(bytes, 0) & 0x7fffffff;

			// build the alphanumeric code
			StringBuilder code = new StringBuilder();
			for (var i=0; i<CODE_DIGITS; i++)
			{
				code.Append(STEAMCHARS[fullcode % STEAMCHARS.Length]);
				fullcode /= (uint)STEAMCHARS.Length;
			}

			return code.ToString();
		}
예제 #23
0
		/// <summary>
		/// Calculate the current code for the authenticator.
		/// Trion's implementation is broken in that they don't built the signed integer correctly from the 4-byte array, so we have to override
		/// the proper method
		/// </summary>
		/// <param name="resyncTime">flag to resync time</param>
		/// <returns>authenticator code</returns>
		protected override string CalculateCode(bool resyncTime = false, long interval = -1)
		{
			// sync time if required
			if (resyncTime == true || ServerTimeDiff == 0)
			{
				if (interval > 0)
				{
					ServerTimeDiff = (interval * 30000L) - CurrentTime;
				}
				else
				{
					Sync();
				}
			}

			HMac hmac = new HMac(new Sha1Digest());
			hmac.Init(new KeyParameter(SecretKey));

			byte[] codeIntervalArray = BitConverter.GetBytes(CodeInterval);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(codeIntervalArray);
			}
			hmac.BlockUpdate(codeIntervalArray, 0, codeIntervalArray.Length);

			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// the last 4 bits of the mac say where the code starts (e.g. if last 4 bit are 1100, we start at byte 12)
			int start = mac[19] & 0x0f;

			// extract those 4 bytes
			byte[] bytes = new byte[4];
			Array.Copy(mac, start, bytes, 0, 4);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(bytes);
			}
			// this is where Trion is broken and their version uses all 32bits
			//uint fullcode = BitConverter.ToUInt32(bytes, 0) & 0x7fffffff;
			uint fullcode = BitConverter.ToUInt32(bytes, 0);

			// we use the last 8 digits of this code in radix 10
			uint codemask = (uint)Math.Pow(10, CodeDigits);
			string format = new string('0', CodeDigits);
			string code = (fullcode % codemask).ToString(format);
			// New glyph authenticator now uses 6, but takes the first 6 of 8 rather the proper last 6, so again we override the standard implementation
			code = code.Substring(0, 6);

			return code;
		}
예제 #24
0
		public Packet ChannelEncrypt(ICipherSetRemoteInfo channelInfo, Packet inner)
		{
			var ci = (CS1ARemoteInfo)channelInfo;

			// TODO:  Validate we don't care about endianess of IV here

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.EncryptionKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Hmac the output
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.EncryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedInner, 0, encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			// Create the outgoing packet
			Packet outPacket = new Packet();
			outPacket.Body = new byte[encryptedInner.Length + 24];
			Buffer.BlockCopy(ci.Token, 0, outPacket.Body, 0, 16);
			Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, outPacket.Body, 16, 4);
			Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 20, encryptedInner.Length);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, outPacket.Body.Length - 4, 4);

			// Next IV next packet
			++ci.IV;

			return outPacket;
		}
예제 #25
0
        /// <summary>
        /// Calculates the MacTag (to be used for key confirmation), as defined by
        /// <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST SP 800-56A Revision 1</a>,
        /// Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes.
        ///
        /// MacTag = HMAC(MacKey, MacLen, MacData)
        /// MacKey = H(K || "JPAKE_KC")
        /// MacData = "KC_1_U" || participantId || partnerParticipantId || gx1 || gx2 || gx3 || gx4
        ///
        /// Note that both participants use "KC_1_U" because the sender of the round 3 message
        /// is always the initiator for key confirmation.
        ///
        /// HMAC = {@link HMac} used with the given {@link Digest}
        /// H = The given {@link Digest}
        /// MacLen = length of MacTag
        /// </summary>
        public static BigInteger CalculateMacTag(string participantId, string partnerParticipantId,
            BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, IDigest digest)
        {
            byte[] macKey = CalculateMacKey(keyingMaterial, digest);

            HMac mac = new HMac(digest);
            mac.Init(new KeyParameter(macKey));
            Arrays.Fill(macKey, (byte)0);

            /*
             * MacData = "KC_1_U" || participantId_Alice || participantId_Bob || gx1 || gx2 || gx3 || gx4.
             */
            UpdateMac(mac, "KC_1_U");
            UpdateMac(mac, participantId);
            UpdateMac(mac, partnerParticipantId);
            UpdateMac(mac, gx1);
            UpdateMac(mac, gx2);
            UpdateMac(mac, gx3);
            UpdateMac(mac, gx4);

            byte[] macOutput = MacUtilities.DoFinal(mac);

            return new BigInteger(macOutput);
        }
예제 #26
0
		public Packet ChannelDecrypt(ICipherSetRemoteInfo channelInfo, Packet outer)
		{
			// We gotta have the primary components and something to decrypt
			if (outer.Body.Length < 25) {
				return null;
			}

			var ci = (CS1ARemoteInfo)channelInfo;

			// Rip apart our packet
			byte[] token = outer.Body.Take (16).ToArray ();
			byte[] iv = outer.Body.Skip (16).Take (4).ToArray ();
			byte[] encryptedData = outer.Body.Skip (20).Take (outer.Body.Length - 24).ToArray ();
			byte[] dataMac = outer.Body.Skip (outer.Body.Length - 4).Take (4).ToArray ();

			// Make sure we're on the right channel
			if (!token.SequenceEqual (ci.Token)) {
				return null;
			}

			// Validate us some hmac
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.DecryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (iv, 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedData, 0, encryptedData.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			if (!foldedMac.SequenceEqual (dataMac)) {
				// Get out of here with your bad data
				return null;
			}

			// Everything seems ok.  Get it decrypted
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (iv, 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.DecryptionKey), aesIV);
			cipher.Init (false, parameters);

			var decryptedData = new byte[encryptedData.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (encryptedData, decryptedData, 0);
			bufferCipher.DoFinal (decryptedData, offset);

			// Build a packet and ship it off
			return Packet.DecodePacket (decryptedData);
		}
예제 #27
0
		/// <summary>
		/// Restore an authenticator from the serial number and restore code.
		/// </summary>
		/// <param name="serial">serial code, e.g. US-1234-5678-1234</param>
		/// <param name="restoreCode">restore code given on enroll, 10 chars.</param>
		public async Task Restore(string serial, string restoreCode)
		{
			// get the serial data
			byte[] serialBytes = Encoding.UTF8.GetBytes(serial.ToUpper().Replace("-", string.Empty));

			// send the request to the server to get our challenge
			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GetMobileUrl(serial) + RESTORE_PATH);
			request.Method = "POST";
			request.ContentType = "application/octet-stream";
			//request.ContentLength = serialBytes.Length;
			Stream requestStream = await request.GetRequestStreamAsync();
			requestStream.Write(serialBytes, 0, serialBytes.Length);
			requestStream.Close();
			byte[] challenge = null;
			try
			{
				using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
				{
					// OK?
					if (response.StatusCode != HttpStatusCode.OK)
					{
						throw new InvalidRestoreResponseException(string.Format("{0}: {1}", (int)response.StatusCode, response.StatusDescription));
					}

					// load back the buffer - should only be a byte[32]
					using (MemoryStream ms = new MemoryStream())
					{
						using (Stream bs = response.GetResponseStream())
						{
							byte[] temp = new byte[RESPONSE_BUFFER_SIZE];
							int read;
							while ((read = bs.Read(temp, 0, RESPONSE_BUFFER_SIZE)) != 0)
							{
								ms.Write(temp, 0, read);
							}
							challenge = ms.ToArray();

							// check it is correct size
							if (challenge.Length != RESTOREINIT_BUFFER_SIZE)
							{
								throw new InvalidRestoreResponseException(string.Format("Invalid response data size (expected 32 got {0})", challenge.Length));
							}
						}
					}
				}
			}
			catch (WebException we)
			{
				int code = (int)((HttpWebResponse)we.Response).StatusCode;
				if (code >= 500 && code < 600)
				{
					throw new InvalidRestoreResponseException(string.Format("No response from server ({0}). Perhaps maintainence?", code));
				}
				else
				{
					throw new InvalidRestoreResponseException(string.Format("Error communicating with server: {0} - {1}", code, ((HttpWebResponse)we.Response).StatusDescription));
				}
			}

			// only take the first 10 bytes of the restore code and encode to byte taking count of the missing chars
			byte[] restoreCodeBytes = new byte[10];
			char[] arrayOfChar = restoreCode.ToUpper().ToCharArray();
			for (int i = 0; i < 10; i++)
			{
				restoreCodeBytes[i] = ConvertRestoreCodeCharToByte(arrayOfChar[i]);
			}

			// build the response to the challenge
			HMac hmac = new HMac(new Sha1Digest());
			hmac.Init(new KeyParameter(restoreCodeBytes));
			byte[] hashdata = new byte[serialBytes.Length + challenge.Length];
			Array.Copy(serialBytes, 0, hashdata, 0, serialBytes.Length);
			Array.Copy(challenge, 0, hashdata, serialBytes.Length, challenge.Length);
			hmac.BlockUpdate(hashdata, 0, hashdata.Length);
			byte[] hash = new byte[hmac.GetMacSize()];
			hmac.DoFinal(hash, 0);

			// create a random key
			byte[] oneTimePad = CreateOneTimePad(20);

			// concatanate the hash and key
			byte[] hashkey = new byte[hash.Length + oneTimePad.Length];
			Array.Copy(hash, 0, hashkey, 0, hash.Length);
			Array.Copy(oneTimePad, 0, hashkey, hash.Length, oneTimePad.Length);

			// encrypt the data with BMA public key
			RsaEngine rsa = new RsaEngine();
			rsa.Init(true, new RsaKeyParameters(false, new Org.BouncyCastle.Math.BigInteger(ENROLL_MODULUS, 16), new Org.BouncyCastle.Math.BigInteger(ENROLL_EXPONENT, 16)));
			byte[] encrypted = rsa.ProcessBlock(hashkey, 0, hashkey.Length);

			// prepend the serial to the encrypted data
			byte[] postbytes = new byte[serialBytes.Length + encrypted.Length];
			Array.Copy(serialBytes, 0, postbytes, 0, serialBytes.Length);
			Array.Copy(encrypted, 0, postbytes, serialBytes.Length, encrypted.Length);

			// send the challenge response back to the server
			request = (HttpWebRequest)WebRequest.Create(GetMobileUrl(serial) + RESTOREVALIDATE_PATH);
			request.Method = "POST";
			request.ContentType = "application/octet-stream";
			//request.ContentLength = postbytes.Length;
			requestStream = await request.GetRequestStreamAsync();
			requestStream.Write(postbytes, 0, postbytes.Length);
			requestStream.Close();
			byte[] secretKey = null;
			try
			{
				using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
				{
					// OK?
					if (response.StatusCode != HttpStatusCode.OK)
					{
						throw new InvalidRestoreResponseException(string.Format("{0}: {1}", (int)response.StatusCode, response.StatusDescription));
					}

					// load back the buffer - should only be a byte[32]
					using (MemoryStream ms = new MemoryStream())
					{
						using (Stream bs = response.GetResponseStream())
						{
							byte[] temp = new byte[RESPONSE_BUFFER_SIZE];
							int read;
							while ((read = bs.Read(temp, 0, RESPONSE_BUFFER_SIZE)) != 0)
							{
								ms.Write(temp, 0, read);
							}
							secretKey = ms.ToArray();

							// check it is correct size
							if (secretKey.Length != RESTOREVALIDATE_BUFFER_SIZE)
							{
								throw new InvalidRestoreResponseException(string.Format("Invalid response data size (expected " + RESTOREVALIDATE_BUFFER_SIZE + " got {0})", secretKey.Length));
							}
						}
					}
				}
			}
			catch (WebException we)
			{
				int code = (int)((HttpWebResponse)we.Response).StatusCode;
				if (code >= 500 && code < 600)
				{
					throw new InvalidRestoreResponseException(string.Format("No response from server ({0}). Perhaps maintainence?", code));
				}
				else if (code >= 600 && code < 700)
				{
					throw new InvalidRestoreCodeException("Invalid serial number or restore code.");
				}
				else
				{
					throw new InvalidRestoreResponseException(string.Format("Error communicating with server: {0} - {1}", code, ((HttpWebResponse)we.Response).StatusDescription));
				}
			}

			// xor the returned data key with our pad to get the actual secret key
			for (int i = oneTimePad.Length - 1; i >= 0; i--)
			{
				secretKey[i] ^= oneTimePad[i];
			}

			// set the authenticator data
			SecretKey = secretKey;
			if (serial.Length == 14)
			{
				Serial = serial.Substring(0, 2).ToUpper() + "-" + serial.Substring(2, 4) + "-" + serial.Substring(6, 4) + "-" + serial.Substring(10, 4);
			}
			else
			{
				Serial = serial.ToUpper();
			}
			// restore code is ok
			RestoreCodeVerified = true;
			// sync the time
			ServerTimeDiff = 0L;
			await Sync();
		}
예제 #28
0
			/// <summary>
			/// Create a new PBKDF2 object
			/// </summary>
			public PBKDF2(byte[] password, byte[] salt, int iterations)
			{
				m_password = password;
				m_salt = salt;
				m_iterations = iterations;

				m_mac = new HMac(new Sha1Digest());
				m_hlen = m_mac.GetMacSize();
			}
예제 #29
0
		/// <summary>
		/// Calculate the current code for the authenticator.
		/// </summary>
		/// <param name="resyncTime">flag to resync time</param>
		/// <returns>authenticator code</returns>
		private string CalculateCode(bool resyncTime)
		{
			// sync time if required
			if (resyncTime == true || ServerTimeDiff == 0)
			{
			  Sync();
			}

			HMac hmac = new HMac(new Sha1Digest());
			hmac.Init(new KeyParameter(SecretKey));

			byte[] codeIntervalArray = BitConverter.GetBytes(CodeInterval);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(codeIntervalArray);
			}
			hmac.BlockUpdate(codeIntervalArray, 0, codeIntervalArray.Length);

			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// the last 4 bits of the mac say where the code starts (e.g. if last 4 bit are 1100, we start at byte 12)
			int start = mac[19] & 0x0f;

			// extract those 4 bytes
			byte[] bytes = new byte[4];
			Array.Copy(mac, start, bytes, 0, 4);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(bytes);
			}
			uint fullcode = BitConverter.ToUInt32(bytes, 0) & 0x7fffffff;

			// we use the last 8 digits of this code in radix 10
			string code = (fullcode % 100000000).ToString("00000000");

			return code;
		}
 public HkdfBytesGenerator(IDigest hash)
 {
     this.hMacHash = new HMac(hash);
     this.hashLength = hash.GetDigestSize();
 }
예제 #31
0
		/// <summary>
		/// Calculate the current code for the authenticator.
		/// </summary>
		/// <param name="resyncTime">flag to resync time</param>
		/// <returns>authenticator code</returns>
		protected virtual string CalculateCode(bool resync = false, long interval = -1)
		{
			// sync time if required
			if (resync == true || ServerTimeDiff == 0)
			{
				if (interval > 0)
				{
					ServerTimeDiff = (interval * 30000L) - CurrentTime;
				}
				else
				{
					Sync();
				}
			}

			HMac hmac = new HMac(new Sha1Digest());
			hmac.Init(new KeyParameter(SecretKey));

			byte[] codeIntervalArray = BitConverter.GetBytes(CodeInterval);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(codeIntervalArray);
			}
			hmac.BlockUpdate(codeIntervalArray, 0, codeIntervalArray.Length);

			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// the last 4 bits of the mac say where the code starts (e.g. if last 4 bit are 1100, we start at byte 12)
			int start = mac[19] & 0x0f;

			// extract those 4 bytes
			byte[] bytes = new byte[4];
			Array.Copy(mac, start, bytes, 0, 4);
			if (BitConverter.IsLittleEndian)
			{
				Array.Reverse(bytes);
			}
			uint fullcode = BitConverter.ToUInt32(bytes, 0) & 0x7fffffff;

			// we use the last 8 digits of this code in radix 10
			uint codemask = (uint)Math.Pow(10, CodeDigits);
			string format = new string('0', CodeDigits);
			string code = (fullcode % codemask).ToString(format);

			return code;
		}