public void GenerateSessionKey(byte[] clientSalt, byte[] serverSalt) { var hmac = new HMACSHA1(SecureRemotePassword.SessionKey); var wow = Encoding.ASCII.GetBytes("WoW\0"); var wowSessionKey = new byte[0x28]; hmac.TransformBlock(wow, 0, wow.Length, wow, 0); hmac.TransformBlock(clientSalt, 0, clientSalt.Length, clientSalt, 0); hmac.TransformFinalBlock(serverSalt, 0, serverSalt.Length); Buffer.BlockCopy(hmac.Hash, 0, wowSessionKey, 0, hmac.Hash.Length); hmac.Initialize(); hmac.TransformBlock(wow, 0, wow.Length, wow, 0); hmac.TransformBlock(serverSalt, 0, serverSalt.Length, serverSalt, 0); hmac.TransformFinalBlock(clientSalt, 0, clientSalt.Length); Buffer.BlockCopy(hmac.Hash, 0, wowSessionKey, hmac.Hash.Length, hmac.Hash.Length); GameAccount.SessionKey = wowSessionKey.ToHexString(); // Update SessionKey in database DB.Auth.Update(GameAccount, "SessionKey"); }
/// <summary> /// returns the hmac of the data and the annotation chunk values (except HMAC chunk itself) /// </summary> public byte[] hmac(byte[] key) { using (HMACSHA1 hmac = new HMACSHA1(key)) { hmac.TransformBlock(this.data, 0, this.data.Length, this.data, 0); foreach (var e in this.annotations.OrderBy(a => a.Key)) { if (e.Key != "HMAC") { hmac.TransformBlock(e.Value, 0, e.Value.Length, e.Value, 0); } } hmac.TransformFinalBlock(this.data, 0, 0); return(hmac.Hash); } }
/// <summary> /// Performs an encryption using AES/CBC/PKCS7 with an input byte array and key, with a IV (comprised of random bytes and the HMAC-SHA1 of the random bytes and plaintext) prepended using AES/ECB/None /// </summary> public static byte[] SymmetricEncryptWithHMACIV(byte[] input, byte[] key, byte[] hmacSecret) { // IV is HMAC-SHA1(Random(3) + Plaintext) + Random(3). (Same random values for both) var iv = new byte[16]; var random = GenerateRandomBlock(3); Array.Copy(random, 0, iv, iv.Length - random.Length, random.Length); using (var hmac = new HMACSHA1(hmacSecret)) { hmac.TransformBlock(random, 0, random.Length, null, 0); hmac.TransformFinalBlock(input, 0, input.Length); Array.Copy(hmac.Hash, iv, iv.Length - random.Length); } return(SymmetricEncryptWithIV(input, key, iv)); }
public byte[] pyrohmac(byte[] data, IDictionary <string, byte[]> annotations) { using (HMACSHA1 hmac = new HMACSHA1(Config.HMAC_KEY)) { hmac.TransformBlock(data, 0, data.Length, data, 0); if (annotations != null) { foreach (var e in annotations) { if (e.Key != "HMAC") { hmac.TransformBlock(e.Value, 0, e.Value.Length, e.Value, 0); } } } hmac.TransformFinalBlock(data, 0, 0); return(hmac.Hash); } }
/// <summary> /// Returns the 10 byte AUTH CODE to be checked or appended immediately following the AES data stream. /// </summary> public byte[] GetAuthCode() { // We usually don't get advance notice of final block. Hash requres a TransformFinal. if (!_finalised) { byte[] dummy = new byte[0]; #if NET45 _hmacsha1.TransformFinalBlock(dummy, 0, 0); #elif NETSTANDARD1_3 _hmacsha1.AppendData(dummy); #endif _finalised = true; } #if NET45 return(_hmacsha1.Hash); #elif NETSTANDARD1_3 return(_hmacsha1.GetHashAndReset()); #endif }
/// <summary> /// Returns the 10 byte AUTH CODE to be checked or appended immediately following the AES data stream. /// </summary> public byte[] GetAuthCode() { // We usually don't get advance notice of final block. Hash requres a TransformFinal. if (!_finalised) { var dummy = new byte[0]; #if !OS_WINDOWS incrementalHash.AppendData(dummy, 0, 0); #else _hmacsha1.TransformFinalBlock(dummy, 0, 0); #endif _finalised = true; } #if !OS_WINDOWS byte[] incrementalA = incrementalHash.GetHashAndReset(); return(incrementalA); #else return(_hmacsha1.Hash); #endif }
private int ReadTransformOneBlock(byte[] buffer, int offset, int last) { if (_finalBlock) { throw new NotSupportedException(); } int bytesRemaining = last - offset; int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES) ? BLOCK_SIZE_IN_BYTES : bytesRemaining; // update the counter System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4); // Determine if this is the final block if ((bytesToRead == bytesRemaining) && (_length > 0) && (_totalBytesXferred + last == _length)) { _mac.TransformFinalBlock(buffer, offset, bytesToRead); counterOut = _xform.TransformFinalBlock(counter, 0, BLOCK_SIZE_IN_BYTES); _finalBlock = true; } else { _mac.TransformBlock(buffer, offset, bytesToRead, null, 0); _xform.TransformBlock(counter, 0, // offset BLOCK_SIZE_IN_BYTES, counterOut, 0); // offset } XorInPlace(buffer, offset, bytesToRead); return(bytesToRead); }
// This function is defined as follow : // Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i) // where i is the block number. private byte[] Func() { byte[] INT_block = Int(m_block); m_hmacsha1.TransformBlock(m_salt, 0, m_salt.Length, m_salt, 0); m_hmacsha1.TransformFinalBlock(INT_block, 0, INT_block.Length); byte[] temp = m_hmacsha1.Hash; m_hmacsha1.Initialize(); byte[] ret = temp; for (int i = 2; i <= m_iterations; i++) { temp = m_hmacsha1.ComputeHash(temp); for (int j = 0; j < BlockSize; j++) { ret[j] ^= temp[j]; } } // increment the block count. m_block++; return(ret); }
private int ReadTransformOneBlock(byte[] buffer, int offset, int last) { if (isFinalBlock) { throw new InvalidOperationException(); } int bytesRemaining = last - offset; int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES) ? BLOCK_SIZE_IN_BYTES : bytesRemaining; // update the counter Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4); // Determine if this is the final block if ((bytesToRead == bytesRemaining) && (totalBytesLeftToRead == 0)) { hmac.TransformFinalBlock(buffer, offset, bytesToRead); counterOut = transform.TransformFinalBlock(counter, 0, BLOCK_SIZE_IN_BYTES); isFinalBlock = true; } else { hmac.TransformBlock(buffer, offset, bytesToRead, null, 0); transform.TransformBlock(counter, 0, // offset BLOCK_SIZE_IN_BYTES, counterOut, 0); // offset } XorInPlace(buffer, offset, bytesToRead); return(bytesToRead); }
/// <summary> /// Returns the SHA1 HMAC of the given <paramref name="prefix"/>, the given <paramref name="request"/>'s /// body, and the given <paramref name="suffix"/> (in that order). /// </summary> /// <param name="request">The current <see cref="HttpRequest"/>.</param> /// <param name="secret">The key data used to initialize the <see cref="HMACSHA1"/>.</param> /// <param name="prefix"> /// If non-<see langword="null"/> and non-empty, additional <c>byte</c>s to include in the hashed content /// before the <paramref name="request"/>'s body. /// </param> /// <param name="suffix"> /// If non-<see langword="null"/> and non-empty, additional <c>byte</c>s to include in the hashed content /// after the <paramref name="request"/>'s body. /// </param> /// <returns> /// A <see cref="Task"/> that on completion provides a <see cref="byte"/> array containing the SHA1 HMAC of /// the <paramref name="prefix"/>, the <paramref name="request"/>'s body, and the <paramref name="suffix"/> /// (in that order). /// </returns> protected virtual async Task <byte[]> ComputeRequestBodySha1HashAsync( HttpRequest request, byte[] secret, byte[] prefix, byte[] suffix) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (secret == null) { throw new ArgumentNullException(nameof(secret)); } if (secret.Length == 0) { throw new ArgumentException(Resources.General_ArgumentCannotBeNullOrEmpty); } await WebHookHttpRequestUtilities.PrepareRequestBody(request); using (var hasher = new HMACSHA1(secret)) { try { if (prefix != null && prefix.Length > 0) { hasher.TransformBlock( prefix, inputOffset: 0, inputCount: prefix.Length, outputBuffer: null, outputOffset: 0); } // Split body into 4K chunks. var buffer = new byte[4096]; var inputStream = request.Body; int bytesRead; while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length)) > 0) { hasher.TransformBlock( buffer, inputOffset: 0, inputCount: bytesRead, outputBuffer: null, outputOffset: 0); } if (suffix != null && suffix.Length > 0) { hasher.TransformBlock( suffix, inputOffset: 0, inputCount: suffix.Length, outputBuffer: null, outputOffset: 0); } hasher.TransformFinalBlock(Array.Empty <byte>(), inputOffset: 0, inputCount: 0); return(hasher.Hash); } finally { // Reset Position because JsonInputFormatter et cetera always start from current position. request.Body.Seek(0L, SeekOrigin.Begin); } } }
private int ProcessOneBlockWriting(byte[] buffer, int offset, int last) { if (_finalBlock) { throw new Exception("The final block has already been transformed."); } int bytesRemaining = last - offset; int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES) ? BLOCK_SIZE_IN_BYTES : bytesRemaining; // update the counter System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4); if (bytesToRead == (last - offset)) { // We're doing the last bytes in this batch. // // For the AES encryption stream to work properly, We must transform full // blocks of 16 bytes each, until the very last one. But, we don't know // how to recognize the "last" bytes. The approach taken here: buffer // the last full or partial block of bytes in a batch. Then at time of // Close(), we set the _NextXformWillBeFinal flag and flush that buffer. // // This works when the caller writes in odd-sized batches, for example // 5000 bytes, or in batches that are neat multiples of block-size (16). if (_NextXformWillBeFinal) { //Console.WriteLine("WinZipAesCipherStream::ProcessOneBlockWriting: _NextXformWillBeFinal = true"); counterOut = _xform.TransformFinalBlock(counter, 0, BLOCK_SIZE_IN_BYTES); _finalBlock = true; } else if (buffer == _PendingWriteBuffer && bytesToRead == BLOCK_SIZE_IN_BYTES) { // Console.WriteLine("POBW({0},{1,5},{2,5}): pc({4}) flushing {3} bytes ...", // _NextXformWillBeFinal, offset, last, bytesToRead, _pendingCount); } else { // NOT the final block, therefore buffer it. // Console.WriteLine("POBW({0},{1,5},{2,5}): pc({4}) buffering {3} more bytes ...", // _NextXformWillBeFinal, offset, last, bytesToRead, _pendingCount); Array.Copy(buffer, offset, _PendingWriteBuffer, _pendingCount, bytesToRead); _pendingCount += bytesToRead; // remember to decrement the nonce. _nonce--; return(0); } } if (!_finalBlock) { // Next, do the AES transform. According to the AES/CTR method used // by WinZip, apply the transform to the counter, and then XOR // the result with the ciphertext to get the plaintext. _xform.TransformBlock(counter, 0, // offset BLOCK_SIZE_IN_BYTES, counterOut, 0); // offset } // XOR (in place) //Console.Write("POBW({0},{1,5},{2,5}): ", _NextXformWillBeFinal, offset, last); for (int i = 0; i < bytesToRead; i++) { buffer[offset + i] = (byte)(counterOut[i] ^ buffer[offset + i]); //Console.Write("{0:X2} ", buffer[offset + i]); } //Console.WriteLine(); // when encrypting, do the MAC last if (_finalBlock) { _mac.TransformFinalBlock(buffer, offset, bytesToRead); } else { _mac.TransformBlock(buffer, offset, bytesToRead, null, 0); } return(bytesToRead); }
private int ProcessOneBlockWriting(byte[] buffer, int offset, int last) { if (_finalBlock) { throw new InvalidOperationException("The final block has already been transformed."); } int bytesRemaining = last - offset; int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES) ? BLOCK_SIZE_IN_BYTES : bytesRemaining; // update the counter System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4); // We're doing the last bytes in this batch. // // For the AES encryption stream to work properly, We must transform // blocks of 16 bytes, via TransformBlock, until the very last one, for // which we call TransformFinalBlock. But, we don't know how to // recognize the "last" bytes. The approach taken here: maintain a // buffer, so that one full or partial block of bytes is always // available. This is the _PendingWriteBuffer. Then at time of // Close(), we set the _NextXformWillBeFinal flag and flush that buffer. // // This works whether the caller writes in odd-sized batches, for example // 5000 bytes, or in batches that are neat multiples of the blocksize (16). // bytesToRead is always 16 or less. If it is exactly what remains, then we need to // either, if this is the final block, do the final transform, else buffer the data. if (bytesToRead == (last - offset)) { if (_NextXformWillBeFinal) { //Console.WriteLine("WinZipAesCipherStream::ProcessOneBlockWriting: _NextXformWillBeFinal = true"); counterOut = _xform.TransformFinalBlock(counter, 0, BLOCK_SIZE_IN_BYTES); _finalBlock = true; } else if (buffer == _PendingWriteBuffer && bytesToRead == BLOCK_SIZE_IN_BYTES) { // this happens with a Flush(), I think. } else { // NOT the final block, therefore buffer it. Array.Copy(buffer, offset, _PendingWriteBuffer, _pendingCount, bytesToRead); _pendingCount += bytesToRead; // remember to decrement the nonce. _nonce--; return(bytesToRead); } } if (!_finalBlock) { // Next, do the AES transform. According to the AES/CTR method used // by WinZip, apply the transform to the counter, and then XOR // the result with the ciphertext to get the plaintext. _xform.TransformBlock(counter, 0, // offset BLOCK_SIZE_IN_BYTES, counterOut, 0); // offset } // XOR (in place) for (int i = 0; i < bytesToRead; i++) { buffer[offset + i] = (byte)(counterOut[i] ^ buffer[offset + i]); } // when encrypting, do the MAC last if (_finalBlock) { _mac.TransformFinalBlock(buffer, offset, bytesToRead); } else { _mac.TransformBlock(buffer, offset, bytesToRead, null, 0); } return(bytesToRead); }
/// <summary> /// <exception cref="IOException"/> /// <exception cref="SpotifyAuthenticatedException"/> /// <exception cref="AccessViolationException"/> /// </summary> private void Connect() { #region ClientHello Setup ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var clientHello = new ClientHello { BuildInfo = new BuildInfo { Platform = Platform.Win32X86, Product = Product.Client, ProductFlags = { ProductFlags.ProductFlagNone }, Version = 112800721 } }; clientHello.CryptosuitesSupported.Add(Cryptosuite.Shannon); clientHello.LoginCryptoHello = new LoginCryptoHelloUnion { DiffieHellman = new LoginCryptoDiffieHellmanHello { Gc = ByteString.CopyFrom(keys.PublicKeyArray()), ServerKeysKnown = 1 } }; var nonce = new byte[16]; (new Random()).NextBytes(nonce); clientHello.ClientNonce = ByteString.CopyFrom(nonce); clientHello.Padding = ByteString.CopyFrom(new byte[1] { (byte)30 }); var clientHelloBytes = clientHello.ToByteArray(); var a = conn.Result.NetworkStream; a.WriteByte(0x00); a.WriteByte(0x04); a.WriteByte(0x00); a.WriteByte(0x00); a.WriteByte(0x00); a.Flush(); var length = 2 + 4 + clientHelloBytes.Length; var bytes = BitConverter.GetBytes(length); a.WriteByte(bytes[0]); a.Write(clientHelloBytes, 0, clientHelloBytes.Length); a.Flush(); var buffer = new byte[1000]; var len = int.Parse(a.Read(buffer, 0, buffer.Length).ToString()); var tmp = new byte[len]; Array.Copy(buffer, tmp, len); tmp = tmp.Skip(4).ToArray(); var accumulator = new MemoryStream(); accumulator.WriteByte(0x00); accumulator.WriteByte(0x04); var lnarr = Utils.toByteArray(length); accumulator.Write(lnarr, 0, lnarr.Length); accumulator.Write((byte[])clientHelloBytes, 0, clientHelloBytes.Length); var lenArr = Utils.toByteArray(len); accumulator.Write(lenArr, 0, lenArr.Length); accumulator.Write((byte[])tmp, 0, tmp.Length); #endregion ClientHello Setup //Read APResponseMessage #region APResponse var binaryData = accumulator.ToArray(); var apResponseMessage = APResponseMessage.Parser.ParseFrom(tmp); var sharedKey = Utils.toByteArray(keys.ComputeSharedKey(apResponseMessage .Challenge.LoginCryptoChallenge.DiffieHellman.Gs.ToByteArray())); // Check gs_signature var rsa = new RSACryptoServiceProvider(); var rsaKeyInfo = new RSAParameters { Modulus = new BigInteger(1, serverKey).ToByteArrayUnsigned(), Exponent = BigInteger.ValueOf(65537).ToByteArrayUnsigned() }; //Set to the public key values. //Import key parameters into RSA. rsa.ImportParameters(rsaKeyInfo); var gs = apResponseMessage.Challenge.LoginCryptoChallenge.DiffieHellman.Gs.ToByteArray(); var sign = apResponseMessage.Challenge.LoginCryptoChallenge.DiffieHellman.GsSignature.ToByteArray(); if (!rsa.VerifyData(gs, sign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1)) { throw new AccessViolationException("Failed to verify APResponse"); } // Solve challenge binaryData = accumulator.ToArray(); using var data = new MemoryStream(); var mac = new HMACSHA1(sharedKey); mac.Initialize(); for (var i = 1; i < 6; i++) { mac.TransformBlock(binaryData, 0, binaryData.Length, null, 0); var temp = new[] { (byte)i }; mac.TransformBlock(temp, 0, temp.Length, null, 0); mac.TransformFinalBlock(new byte[0], 0, 0); var final = mac.Hash; data.Write(final, 0, final.Length); mac = new HMACSHA1(sharedKey); } var dataArray = data.ToArray(); mac = new HMACSHA1(Arrays.CopyOfRange(dataArray, 0, 0x14)); mac.TransformBlock(binaryData, 0, binaryData.Length, null, 0); mac.TransformFinalBlock(new byte[0], 0, 0); var challenge = mac.Hash; var clientResponsePlaintext = new ClientResponsePlaintext { LoginCryptoResponse = new LoginCryptoResponseUnion { DiffieHellman = new LoginCryptoDiffieHellmanResponse { Hmac = ByteString.CopyFrom(challenge) } }, PowResponse = new PoWResponseUnion(), CryptoResponse = new CryptoResponseUnion() }; var clientResponsePlaintextBytes = clientResponsePlaintext.ToByteArray(); len = 4 + clientResponsePlaintextBytes.Length; a.WriteByte(0x00); a.WriteByte(0x00); a.WriteByte(0x00); var bytesb = BitConverter.GetBytes(len); a.WriteByte(bytesb[0]); a.Write(clientResponsePlaintextBytes, 0, clientResponsePlaintextBytes.Length); a.Flush(); try { var scrap = new byte[4]; conn.Result.NetworkStream.ReadTimeout = 300; var read = conn.Result.NetworkStream.Read(scrap, 0, scrap.Length); if (read == scrap.Length) { length = (scrap[0] << 24) | (scrap[1] << 16) | (scrap[2] << 8) | (scrap[3] & 0xFF); var payload = new byte[length - 4]; conn.Result.NetworkStream.ReadComplete(payload, 0, payload.Length); var failed = APResponseMessage.Parser.ParseFrom(payload)?.LoginFailed; throw new SpotifyAuthenticatedException(failed); } else if (read > 0) { throw new Exception("Read unknown data!"); } } catch (Exception x) { // ignored } finally { conn.Result.NetworkStream.ReadTimeout = Timeout.Infinite; } using (authLock.Lock()) { sendCipher = new Shannon(); sendCipher.key(Arrays.CopyOfRange(data.ToArray(), 0x14, 0x34)); recvCipher = new Shannon(); recvCipher.key(Arrays.CopyOfRange(data.ToArray(), 0x34, 0x54)); authLockEventWaitHandle.Set(); } #endregion APResponse Debug.WriteLine("Connected successfully"); }
public void addElement(String s) { //word=binascii.a2b_qp(qgram) # convert to binary String mykey = "zuxujesw"; byte[] keyBytes = Encoding.UTF8.GetBytes(mykey); String hex1 = ""; String hex2 = ""; try { HMACSHA1 mac = new HMACSHA1(keyBytes); mac.Initialize(); byte[] inputBytes = new byte[s.Length]; for (var i = 0; i < s.Length; i++) { inputBytes.SetValue(Convert.ToByte(s[i]), i);//Encoding.UTF8.GetBytes(s); } byte[] digest = mac.TransformFinalBlock(inputBytes, 0, inputBytes.Length); hex1 = BitConverter.ToString(digest).Replace("-", string.Empty); } catch (Exception ex) { Console.Error.WriteLine("HMACSHA1: Hash error: " + ex.Message); } try { HMACMD5 mac = new HMACMD5(keyBytes); mac.Initialize(); byte[] inputBytes = Encoding.UTF8.GetBytes(s); byte[] digest = mac.TransformFinalBlock(inputBytes, 0, inputBytes.Length); hex2 = BitConverter.ToString(digest).Replace("-", string.Empty); } catch (Exception ex) { Console.Error.WriteLine("HMACMD5: Hash error: " + ex.Message); } // convert hash key to integer BigInteger h1 = BigInteger.Parse(hex1, NumberStyles.AllowHexSpecifier); BigInteger h2 = BigInteger.Parse(hex2, NumberStyles.AllowHexSpecifier); for (int i = 0; i < k; i++) { BigInteger bigi = new BigInteger(i); //BigInteger res = h2.multiply(bigi).add(h1).mod(new BigInteger(this.bitSetSize + "")); BigInteger res = (h2 * bigi + h1) % new BigInteger(this.bitSetSize); int position = (int)res; if (!bitset.get(position)) { bitsSet++; } if (bitset.get(position)) { if (cols[position] == 0) { cols[position] = 1; } else { cols[position] = cols[position] + 1; } } bitset.set(position); } numberOfAddedElements++; }