📄 expansionderivebytes.cs
字号:
/*
* Mentalis.org Security Library
*
* Copyright ?2002-2005, The KPD-Team
* All rights reserved.
* http://www.mentalis.org/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the KPD-Team, nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Text;
using System.Security.Cryptography;
using Org.Mentalis.Security.Cryptography;
namespace Org.Mentalis.Security.Ssl.Tls1 {
/* P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
HMAC_hash(secret, A(2) + seed) +
HMAC_hash(secret, A(3) + seed) + ...
Where + indicates concatenation.
A() is defined as:
A(0) = seed
A(i) = HMAC_hash(secret, A(i-1))
*/
internal class ExpansionDeriveBytes : DeriveBytes, IDisposable {
public ExpansionDeriveBytes(HashAlgorithm hash, byte[] secret, string seed) {
if (seed == null)
throw new ArgumentNullException();
Initialize(hash, secret, Encoding.ASCII.GetBytes(seed));
}
public ExpansionDeriveBytes(HashAlgorithm hash, byte[] secret, byte[] seed) {
Initialize(hash, secret, seed);
}
protected void Initialize(HashAlgorithm hash, byte[] secret, byte[] seed) {
if (seed == null || secret == null || hash == null)
throw new ArgumentNullException();
m_Disposed = false;
m_HMAC = new Org.Mentalis.Security.Cryptography.HMAC(hash, secret);
m_Seed = seed;
m_HashSize = m_HMAC.HashSize / 8;
Reset();
}
protected byte[] GetNextBytes() {
m_HMAC.TransformBlock(m_Ai, 0, m_HashSize, m_Ai, 0);
m_HMAC.TransformFinalBlock(m_Seed, 0, m_Seed.Length);
byte[] ret = m_HMAC.Hash;
m_HMAC.Initialize();
// calculate next A
m_Ai = m_HMAC.ComputeHash(m_Ai);
return ret;
}
public override byte[] GetBytes(int cb) { // get the next bytes
if (m_Disposed)
throw new ObjectDisposedException(this.GetType().FullName);
if (cb < 0)
throw new ArgumentException();
byte[] ret = new byte[cb];
byte[] temp;
int filled = 0;
while(filled < ret.Length) {
if (filled + m_NextBytes.Length >= cb) {
Array.Copy(m_NextBytes, 0, ret, filled, cb - filled);
temp = new byte[m_NextBytes.Length - (cb - filled)];
Array.Copy(m_NextBytes, m_NextBytes.Length - temp.Length, temp, 0, temp.Length);
m_NextBytes = temp;
filled = ret.Length;
} else {
Array.Copy(m_NextBytes, 0, ret, filled, m_NextBytes.Length);
filled += m_NextBytes.Length;
m_NextBytes = GetNextBytes();
}
}
return ret;
}
public override void Reset() {
if (m_Disposed)
throw new ObjectDisposedException(this.GetType().FullName);
m_Ai = m_HMAC.ComputeHash(m_Seed); // A(1)
m_NextBytes = GetNextBytes();
}
public void Dispose() {
if (!m_Disposed) {
m_Disposed = true;
m_HMAC.Clear();
Array.Clear(m_Seed, 0, m_Seed.Length);
Array.Clear(m_Ai, 0, m_Ai.Length);
Array.Clear(m_NextBytes, 0, m_NextBytes.Length);
}
}
~ExpansionDeriveBytes() {
Dispose();
}
private Org.Mentalis.Security.Cryptography.HMAC m_HMAC;
private int m_HashSize; // in bytes
private byte[] m_Seed;
private byte[] m_NextBytes;
private byte[] m_Ai;
private bool m_Disposed;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -