/// <summary>BouncyCastleでMacのハッシュ値を計算して返す。</summary> /// <param name="data">データ(バイト配列)</param> /// <param name="key">キー(バイト配列)</param> /// <param name="mac">IMac</param> /// <returns>ハッシュ値(バイト配列)</returns> public static byte[] GetMacBytesByBC(byte[] data, byte[] key, IMac mac) { mac.Init(new KeyParameter(key)); mac.BlockUpdate(data, 0, data.Length); byte[] rtnVal = new byte[mac.GetMacSize()]; mac.DoFinal(rtnVal, 0); if (mac.AlgorithmName == "DESede/CBC" && 8 < rtnVal.Length) { rtnVal = ArrayOperator.CopyArray <byte>(rtnVal, 8); } return(rtnVal); // <HMAC> // mac = new HMac(new RipeMD160Digest()); // <MACTripleDES> // mac = new CbcBlockCipherMac(new DesEdeEngine(), 64)); // https://www.go4expert.com/articles/bouncy-castle-net-implementation-triple-t24829/ // ECBモードのDESEDEと、CBCモードのTriple DESがある。 // https://stackoverflow.com/questions/34660907/how-to-encrypt-decrypt-string-using-mactripledes // MACTripleDESはCBC-MACを使用します。 CBC-MACは、メッセージにゼロを埋め込んだ後にCBCモードを使用します。 }
/// <summary>初期化(プロバイダ)</summary> /// <param name="forEncrypt">bool</param> private void InitAesCbc(bool forEncrypt) { // PaddedBufferedBlockCipher this._aesCBC = new PaddedBufferedBlockCipher( new CbcBlockCipher(new AesEngine()), new Pkcs7Padding()); // Initialization Vector. // IV must be the same length as block size this.IV = ArrayOperator.CopyArray <byte>(this.IV, this._aesCBC.GetBlockSize()); // 初期化 // EncKey length is 128 / 192 / 256 bits. this._aesCBC.Reset(); this._aesCBC.Init(forEncrypt, new ParametersWithIV( new KeyParameter(this.EncKey, 0, this.EncKey.Length), this.IV)); // MacKey this._hmac.Initialize(); this._hmac.Key = this.MacKey; }
/// <summary>constructor</summary> /// <param name="cek">コンテンツ暗号化キー(CEK)</param> /// <param name="iv">初期化ベクトル</param> /// <param name="aad">追加認証データ(AAD)</param> public AeadAesCbc(byte[] cek, byte[] iv, byte[] aad) : base(cek, iv, aad) { // 各種サイズの初期化 this.InitSize(); // CEK -> MacKey & EncKey if (cek.Length < CEK_LEN) { throw new ArgumentException(string.Format("Length is less than {0} bytes.", this.CEK_LEN), "cek"); } this.MacKey = ArrayOperator.CopyArray <byte>(cek, MAC_KEY_LEN); this.EncKey = ArrayOperator.CopyArray <byte>(cek, ENC_KEY_LEN, ENC_KEY_LEN, 0); // Initialization Vector. this.IV = iv; // Additional Authenticated Data this.AAD = aad; // HMac this.AL = this.InitAL(); }
/// <summary>constructor</summary> /// <param name="cek">コンテンツ暗号化キー(CEK)</param> /// <param name="iv">初期化ベクトル</param> /// <param name="aad">追加認証データ(AAD)</param> public AeadAesGcm(byte[] cek, byte[] iv, byte[] aad) : base(cek, iv, aad) { // 各種サイズの初期化 this.InitSize(); if (cek.Length < CEK_LEN) { throw new ArgumentException("Length is less than 128 bits.", "cek"); } else if (cek.Length == CEK_LEN) { this.Cek = cek; } else { this.Cek = ArrayOperator.CopyArray(cek, CEK_LEN); } // Use of an IV of size 96 bits is REQUIRED with this algorithm. this._iv = iv; // The requested size of the Authentication Tag output MUST be 128 bits, regardless of the key size. this._aad = aad; }
/// <summary>暗号化</summary> /// <param name="plaint">平文(plaintext)</param> /// <returns>AEAD実行結果オブジェクト</returns> public override void Encrypt(byte[] plaint) { // AesGcm実装を初期化 this.InitAesGcm(true); // GCM操作の実行 byte[] aead = new byte[this._aesGcm.GetOutputSize(plaint.Length)]; int len = this._aesGcm.ProcessBytes(plaint, 0, plaint.Length, aead, 0); len += this._aesGcm.DoFinal(aead, len); // GetMacで認証タグ(MAC)を取得 byte[] tag = this._aesGcm.GetMac(); // 結果を返す this._result = new AeadResult() { Aead = aead, // aead = ciphert + tag // <ciphertの抽出> // plaint.Lengthと、ciphert.Length - tag.Length を使う方法がある。 Ciphert = ArrayOperator.CopyArray <byte>(aead, plaint.Length), Tag = tag, }; }