private byte[] GetDerivative(byte[] seed, byte[] key) { try { using(var hmac = new HMACSHA256(key)) { hmac.TransformFinalBlock(seed, 0, seed.Length); return hmac.Hash; } } catch { throw new InvalidOperationException ("Assertion error"); } }
public void CheckE (string testName, byte[] key, byte[] data, byte[] result) { algo = new HMACSHA256 (); algo.Key = key; byte[] copy = new byte [data.Length]; // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! for (int i=0; i < data.Length - 1; i++) algo.TransformBlock (data, i, 1, copy, i); algo.TransformFinalBlock (data, data.Length - 1, 1); Assert.AreEqual (result, algo.Hash, testName + "e"); }
public void CheckD (string testName, byte[] key, byte[] data, byte[] result) { algo = new HMACSHA256 (); algo.Key = key; // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue ! algo.TransformFinalBlock (data, 0, data.Length); Assert.AreEqual (result, algo.Hash, testName + "d"); }
/// <summary> /// Compute PBKDF2 using HMAC-SHA256 as the PRF, and write the output to derivedKey. /// </summary> private static void PBKDF2_SHA256(HMACSHA256 mac, byte[] password, byte[] salt, int saltLength, long iterationCount, byte[] derivedKey, int derivedKeyLength) { if (derivedKeyLength > (Math.Pow(2, 32) - 1) * 32) { throw new ArgumentException("Requested key length too long"); } var U = new byte[32]; var T = new byte[32]; var saltBuffer = new byte[saltLength + 4]; var blockCount = (int)Math.Ceiling((double)derivedKeyLength / 32); var r = derivedKeyLength - (blockCount - 1) * 32; Buffer.BlockCopy(salt, 0, saltBuffer, 0, saltLength); for (int i = 1; i <= blockCount; i++) { saltBuffer[saltLength + 0] = (byte)(i >> 24); saltBuffer[saltLength + 1] = (byte)(i >> 16); saltBuffer[saltLength + 2] = (byte)(i >> 8); saltBuffer[saltLength + 3] = (byte)(i); mac.Initialize(); mac.TransformFinalBlock(saltBuffer, 0, saltBuffer.Length); Buffer.BlockCopy(mac.Hash, 0, U, 0, U.Length); Buffer.BlockCopy(U, 0, T, 0, 32); for (long j = 1; j < iterationCount; j++) { mac.TransformFinalBlock(U, 0, U.Length); Buffer.BlockCopy(mac.Hash, 0, U, 0, U.Length); for (int k = 0; k < 32; k++) { T[k] ^= U[k]; } } Buffer.BlockCopy(T, 0, derivedKey, (i - 1) * 32, (i == blockCount ? r : 32)); } }
private void WriteSafeBlock() { byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex); int cbBlockSize = m_iBufferPos; byte[] pbBlockSize = MemUtil.Int32ToBytes(cbBlockSize); byte[] pbBlockHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); if(cbBlockSize > 0) h.TransformBlock(m_pbBuffer, 0, cbBlockSize, m_pbBuffer, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbBlockHmac = h.Hash; } MemUtil.ZeroByteArray(pbBlockKey); MemUtil.Write(m_sBase, pbBlockHmac); // MemUtil.Write(m_sBase, pbBlockIndex); // Implicit MemUtil.Write(m_sBase, pbBlockSize); if(cbBlockSize > 0) m_sBase.Write(m_pbBuffer, 0, cbBlockSize); ++m_uBlockIndex; m_iBufferPos = 0; }
private bool ReadSafeBlock() { if(m_bEos) return false; // End of stream reached already byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32); if((pbStoredHmac == null) || (pbStoredHmac.Length != 32)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); // Block index is implicit: it's used in the HMAC computation, // but does not need to be stored // byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8); // if((pbBlockIndex == null) || (pbBlockIndex.Length != 8)) // throw new EndOfStreamException(); // ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex); // if((uBlockIndex != m_uBlockIndex) && m_bVerify) // throw new InvalidDataException(); byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex); byte[] pbBlockSize = MemUtil.Read(m_sBase, 4); if((pbBlockSize == null) || (pbBlockSize.Length != 4)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); int nBlockSize = MemUtil.BytesToInt32(pbBlockSize); if(nBlockSize < 0) throw new InvalidDataException(KLRes.FileCorrupted); m_iBufferPos = 0; m_pbBuffer = MemUtil.Read(m_sBase, nBlockSize); if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncompleteExpc); if(m_bVerify) { byte[] pbCmpHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); if(m_pbBuffer.Length > 0) h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length, m_pbBuffer, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbCmpHmac = h.Hash; } MemUtil.ZeroByteArray(pbBlockKey); if(!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac)) throw new InvalidDataException(KLRes.FileCorrupted); } ++m_uBlockIndex; if(nBlockSize == 0) { m_bEos = true; return false; // No further data available } return true; }
private static void HmacEval(byte[] pbKey, byte[] pbMsg, byte[] pbExpc, string strID) { using(HMACSHA256 h = new HMACSHA256(pbKey)) { h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbHash = h.Hash; if(!MemUtil.ArraysEqual(pbHash, pbExpc)) throw new SecurityException("HMAC-SHA-256-" + strID); // Reuse the object h.Initialize(); h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbHash = h.Hash; if(!MemUtil.ArraysEqual(pbHash, pbExpc)) throw new SecurityException("HMAC-SHA-256-" + strID + "-R"); } }
private byte[] GetMac(UInt32 messageVersion, IdentityKey senderIdentityKey, IdentityKey receiverIdentityKey, byte[] macKey, byte[] serialized) { try { byte[] fullMac; using(var mac = new HMACSHA256(macKey)) { if(messageVersion >= 3) { var SIk = senderIdentityKey.PublicKey.Serialize(); var RIk = receiverIdentityKey.PublicKey.Serialize(); mac.TransformBlock(SIk, 0, SIk.Length, null, 0); mac.TransformBlock(RIk, 0, RIk.Length, null, 0); } fullMac = mac.TransformFinalBlock(serialized, 0, serialized.Length); } return ByteUtil.Trim(fullMac, MAC_LENGTH); } catch(Exception e) { throw new InvalidOperationException("Assertion error", e); } }
public static byte[] Pbkdf2(byte[] password, byte[] salt, int iterations = Pbkdf2Iterations) { /* // Algorithm Credits to https://github.com/vexocide // // Implements PBKDF2WithHmacSHA256 in Java. Beautifully Amazing. using (var mac = new HMACSHA256(password)) { mac.TransformBlock(salt, 0, salt.Length, salt, 0); byte[] i = { 0, 0, 0, 1 }; mac.TransformFinalBlock(i, 0, i.Length); byte[] t = mac.Hash; mac.Initialize(); byte[] u = t; for (uint c = 2; c <= iterations; c++) { t = mac.ComputeHash(t); for (int j = 0; j < mac.HashSize / 8; j++) { u[j] ^= t[j]; } } return u; } */ #if STANDARD using( var macSalt = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, password) ) #endif using ( var mac = new HMACSHA256(password) ) { #if STANDARD macSalt.AppendData(salt); #else mac.TransformBlock(salt, 0, salt.Length, salt, 0); #endif byte[] i = {0, 0, 0, 1}; #if STANDARD macSalt.AppendData(i); #else mac.TransformFinalBlock(i, 0, i.Length); #endif #if STANDARD byte[] t = macSalt.GetHashAndReset(); #else byte[] t = mac.Hash; mac.Initialize(); #endif byte[] u = t; for( uint c = 2; c <= iterations; c++ ) { t = mac.ComputeHash(t); for( int j = 0; j < mac.HashSize / 8; j++ ) { u[j] ^= t[j]; } } return u; } }
private void button2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == DialogResult.OK) { SaveFileDialog sfd = new SaveFileDialog(); if (sfd.ShowDialog() == DialogResult.OK) { try { byte[] AES_KEY = { 0xB4, 0xEB, 0x7F, 0xB9, 0xA9, 0xAC, 0x05, 0x92, 0xAB, 0x8E, 0x42, 0xAB, 0xCC, 0x61, 0xD0, 0xC0 }; byte[] HMAC_KEY = { 0x82, 0xF4, 0x1A, 0x4F, 0x03, 0x45, 0x65, 0x01, 0x2F, 0x73, 0x9C, 0x4D, 0x8E, 0x63, 0xA9, 0x1F, 0xB9, 0x2B, 0x9D, 0x4E, 0xE1, 0x11, 0x91, 0x47, 0xD4, 0x3C, 0xC6, 0x88, 0x3F, 0xC7, 0xFC, 0x70 }; BinaryReader reader = new BinaryReader(new FileStream(ofd.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)); BinaryWriter writer = new BinaryWriter(new FileStream(sfd.FileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)); byte[] ProfileID = HexStringToByteArray(textBox1.Text); if (reader.ReadUInt32() != 0x73736D63) throw new Exception("Invalid File"); uint ReadSize = BSwapUint(reader.ReadUInt32()); byte[] Hash = reader.ReadBytes(0x20); uint DataSizeEnc = BSwapUint(reader.ReadUInt32()); byte[] AES_IV = reader.ReadBytes(0x10); uint DataSizeDec = DecryptDataSize(AES_IV, DataSizeEnc); byte[] DataBuffer = reader.ReadBytes((int)(DataSizeDec)); XorAes(ref AES_KEY, ProfileID, 1); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.None; byte[] Encrypted = aes.CreateEncryptor(AES_KEY, AES_IV).TransformFinalBlock(DataBuffer, 0, DataBuffer.Length); XorHmac(ref HMAC_KEY, ProfileID, 0); HMACSHA256 hmac = new HMACSHA256(HMAC_KEY); byte[] Tmp = new byte[0x14]; Buffer.BlockCopy(BitConverter.GetBytes(BSwapUint(DataSizeEnc)), 0, Tmp, 0, 4); Buffer.BlockCopy(AES_IV, 0, Tmp, 4, 0x10); hmac.TransformBlock(Tmp, 0, 0x14, null, 0); hmac.TransformFinalBlock(Encrypted, 0, Encrypted.Length); writer.Write(0x73736D63); writer.Write(BSwapUint(ReadSize)); writer.Write(hmac.Hash); writer.Write(BSwapUint(DataSizeEnc)); writer.Write(AES_IV); writer.Write(Encrypted); writer.Flush(); writer.Close(); reader.Close(); } catch (Exception x) { MessageBox.Show(x.Message); } } } }
/// <summary> /// Prepares an authentication tag. /// Authentication Tag = HMAC_SHA-2-256(mac_key, versionbyte + cell_iv + cell_ciphertext + versionbyte_length) /// </summary> /// <param name="cipherText"></param> /// <returns></returns> private byte[] PrepareAuthenticationTag(byte[] iv, byte[] cipherText, int offset, int length) { Debug.Assert(cipherText != null); byte[] computedHash; byte[] authenticationTag = new byte[_KeySizeInBytes]; // Raw Tag Length: // 1 for the version byte // 1 block for IV (16 bytes) // cipherText.Length // 1 byte for version byte length using (HMACSHA256 hmac = new HMACSHA256(_columnEncryptionKey.MACKey)) { int retVal = 0; retVal = hmac.TransformBlock(_version, 0, _version.Length, _version, 0); Debug.Assert(retVal == _version.Length); retVal = hmac.TransformBlock(iv, 0, iv.Length, iv, 0); Debug.Assert(retVal == iv.Length); retVal = hmac.TransformBlock(cipherText, offset, length, cipherText, offset); Debug.Assert(retVal == length); hmac.TransformFinalBlock(_versionSize, 0, _versionSize.Length); computedHash = hmac.Hash; } Debug.Assert (computedHash.Length >= authenticationTag.Length); Buffer.BlockCopy (computedHash, 0, authenticationTag, 0, authenticationTag.Length); return authenticationTag; }
/// <summary> /// Encryption Algorithm /// cell_iv = HMAC_SHA-2-256(iv_key, cell_data) truncated to 128 bits /// cell_ciphertext = AES-CBC-256(enc_key, cell_iv, cell_data) with PKCS7 padding. /// (optional) cell_tag = HMAC_SHA-2-256(mac_key, versionbyte + cell_iv + cell_ciphertext + versionbyte_length) /// cell_blob = versionbyte + [cell_tag] + cell_iv + cell_ciphertext /// </summary> /// <param name="plainText">Plaintext data to be encrypted</param> /// <param name="hasAuthenticationTag">Does the algorithm require authentication tag.</param> /// <returns>Returns the ciphertext corresponding to the plaintext.</returns> protected byte[] EncryptData(byte[] plainText, bool hasAuthenticationTag) { // Empty values get encrypted and decrypted properly for both Deterministic and Randomized encryptions. Debug.Assert(plainText != null); byte[] iv = new byte[_BlockSizeInBytes]; // Prepare IV // Should be 1 single block (16 bytes) if (_isDeterministic) { SqlSecurityUtility.GetHMACWithSHA256(plainText, _columnEncryptionKey.IVKey, iv); } else { SqlSecurityUtility.GenerateRandomBytes(iv); } int numBlocks = plainText.Length / _BlockSizeInBytes + 1; // Final blob we return = version + HMAC + iv + cipherText const int hmacStartIndex = 1; int authenticationTagLen = hasAuthenticationTag ? _KeySizeInBytes : 0; int ivStartIndex = hmacStartIndex + authenticationTagLen; int cipherStartIndex = ivStartIndex + _BlockSizeInBytes; // this is where hmac starts. // Output buffer size = size of VersionByte + Authentication Tag + IV + cipher Text blocks. int outputBufSize = sizeof(byte) + authenticationTagLen + iv.Length + (numBlocks*_BlockSizeInBytes); byte[] outBuffer = new byte[outputBufSize]; // Store the version and IV rightaway outBuffer[0] = _algorithmVersion; Buffer.BlockCopy(iv, 0, outBuffer, ivStartIndex, iv.Length); AesCryptoServiceProvider aesAlg; // Try to get a provider from the pool. // If no provider is available, create a new one. if (!_cryptoProviderPool.TryDequeue(out aesAlg)) { aesAlg = new AesCryptoServiceProvider(); try { // Set various algorithm properties aesAlg.Key = _columnEncryptionKey.EncryptionKey; aesAlg.Mode = _cipherMode; aesAlg.Padding = _paddingMode; } catch (Exception) { if (aesAlg != null) { aesAlg.Dispose(); } throw; } } try { // Always set the IV since it changes from cell to cell. aesAlg.IV = iv; // Compute CipherText and authentication tag in a single pass using (ICryptoTransform encryptor = aesAlg.CreateEncryptor()) { Debug.Assert(encryptor.CanTransformMultipleBlocks, "AES Encryptor can transform multiple blocks"); int count = 0; int cipherIndex = cipherStartIndex; // this is where cipherText starts if (numBlocks > 1) { count = (numBlocks - 1) * _BlockSizeInBytes; cipherIndex += encryptor.TransformBlock(plainText, 0, count, outBuffer, cipherIndex); } byte[] buffTmp = encryptor.TransformFinalBlock(plainText, count, plainText.Length - count); // done encrypting Buffer.BlockCopy(buffTmp, 0, outBuffer, cipherIndex, buffTmp.Length); cipherIndex += buffTmp.Length; } if (hasAuthenticationTag) { using (HMACSHA256 hmac = new HMACSHA256(_columnEncryptionKey.MACKey)) { Debug.Assert(hmac.CanTransformMultipleBlocks, "HMAC can't transform multiple blocks"); hmac.TransformBlock(_version, 0, _version.Length, _version, 0); hmac.TransformBlock(iv, 0, iv.Length, iv, 0); // Compute HMAC on final block hmac.TransformBlock(outBuffer, cipherStartIndex, numBlocks * _BlockSizeInBytes, outBuffer, cipherStartIndex); hmac.TransformFinalBlock(_versionSize, 0, _versionSize.Length); byte[] hash = hmac.Hash; Debug.Assert(hash.Length >= authenticationTagLen, "Unexpected hash size"); Buffer.BlockCopy(hash, 0, outBuffer, hmacStartIndex, authenticationTagLen); } } } finally { // Return the provider to the pool. _cryptoProviderPool.Enqueue(aesAlg); } return outBuffer; }