4

HMAC で署名されたメッセージがあり、そのメッセージと HMAC が暗号化され、TCP ソケット経由で送信されるとします。

// endpoint info excluded
TcpClient client = new TcpClient();
var stream = client.GetStream();

// assume pre-shared keys are used and set at this point
AesManaged aes = new AesManaged();
var aesEncryptor = aes.CreateEncryptor();
CryptoStream aesStream = new CryptoStream(
    stream, aesEncryptor, CryptoStreamMode.Write);

// assume pre-shared keys here too
HMACSHA256 mac = new HMACSHA256();
CryptoStream macStream = new CryptoStream(
    aesStream, mac, CryptoStreamMode.Write);

// assume a message with actual data is written to the macStream
// which updates the hash of the HMAC and also pipes the message
// to the aesStream which encrypts the data and writes it to the
// TCP socket stream
byte[] message = new byte[1024];
macStream.Write(message, 0, message.Length);
macStream.FlushFinalBlock();

// flushing the final block of the macStream actually flushes the
// final block of the aesStream, so I get an error when trying to
// write the HMAC hash to the aesStream
aesStream.Write(mac.Hash, 0, mac.Hash.Length);
aesStream.FlushFinalBlock();

多くのコードを抽象化したので、これは実際の例ではありません。HMAC.TransformBlock に 1 回、aesStream に 1 回、データを 2 回書き込むことで、おそらくこれを回避できますが、それは避けたいと思います。何か案は?

4

3 に答える 3

2

特にソケット経由でデータを送信する場合は、MAC の前に暗号化を実行して安全なソリューションを作成する必要があります (オラクル攻撃のパディングに対して脆弱になる可能性があるため)。したがって、質問は有効ですが、ストリームの順序を変更することをお勧めします。

于 2013-03-01T00:05:47.140 に答える
0

そこで、今のところ機能しているように見えるハックを配置しました。と呼ばれるストリームラッパークラスを作成しましたProtectedStream。要点は次のとおりです。

public class ProtectedStream : Stream
{
  private Stream stream;

  public ProtectedStream(Stream stream)
  {
    if(stream == null)
      throw new ArgumentNullException("stream");

    this.stream = stream;
  }

  public override void Close()
  {
    this.stream.Close();
    base.Close();
  }

  public override int Read(byte[] buffer, int offset, int count)
  {
    return this.stream.Read(buffer, offset, count);
  }

  public override void Write(byte[] buffer, int offset, int count)
  {
    this.stream.Write(buffer, offset, count);
  }

  // and continue overriding every other overridable Stream member
  // in the same fashion
}

そして、元のコードは次のようになります。

// assume pre-shared keys are used and set at this point
AesManaged aes = new AesManaged();
var aesEncryptor = aes.CreateEncryptor();
CryptoStream aesStream = new CryptoStream(
    stream, aesEncryptor, CryptoStreamMode.Write);

// assume pre-shared keys here too
HMACSHA256 mac = new HMACSHA256();
CryptoStream macStream = new CryptoStream(
    new ProtectedStream(aesStream), mac, CryptoStreamMode.Write);

aesStreamで囲まれていることに注意してくださいProtectedStreamaesStreamこれは、CryptoStreamからであるという事実を隠しているmacStreamので、あなたがそれを呼び出すときFlushFinalBlock、それはをmacStream呼び出さない。FlushFinalBlockaesStream

于 2013-03-01T00:57:18.467 に答える