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(); } }
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; }
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); }
/** * 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; }
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 ) ); }
/** * 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); }
/// <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; }
/// <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}; }
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); ; }
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; }
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 }
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(); }
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]; } } }
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"); }
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; }
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))); } }
/** * 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()]; }
/// <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(); }
/// <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; }
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; }
/// <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); }
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); }
/// <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(); }
/// <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(); }
/// <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(); }
/// <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; }