備忘録

備忘録

C# でBouncyCastleを使ってRijndael 鍵長256bit, ブロック長256bitで暗号化する

Ⅰ. はじめに

  • .NET Core標準のRijndael実装は鍵長256bit、ブロック長256bitがサポートされていません。
  • 鍵長256bit、ブロック長 256bit のRijndael を利用したい場合は、それなりに利用数が多いBouncyCastleを利用するのがベターかと思います。

Ⅱ. やり方

1. NuGetで Portable.BouncyCastle をインストールする

Install-Package Portable.BouncyCastle

2. Rijndael の暗号化、複合のサンプル

using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;

namespace RijndaelTest
{
    class BouncyCastleRijndael
    {
        static byte[] key;
        static byte[] iv;
        static PaddedBufferedBlockCipher cipher;
        static ParametersWithIV parametersWithIV;

        static BouncyCastleRijndael()
        {
            key = Encoding.UTF8.GetBytes("13e990b91d7e48b89e6b04372900d3b6");
            iv = Encoding.UTF8.GetBytes("2aab0b4007de49f8aa9f9a4fd3286067");
            
            // Rijndael
            // Mode = CBC
            // BlockSize = 256bit
            // PaddingMode = Zero
            var cbcBlockCipher = new CbcBlockCipher(new RijndaelEngine(256));
            cipher = new PaddedBufferedBlockCipher(cbcBlockCipher, new ZeroBytePadding());
            parametersWithIV = new ParametersWithIV(new KeyParameter(key), iv);
        }

        public static string Encrypt(string str)
        {
            var data = Encoding.UTF8.GetBytes(str);

            cipher.Init(true, parametersWithIV);
            var bytes = new byte[cipher.GetOutputSize(data.Length)];
            var length = cipher.ProcessBytes(data, bytes, 0);
            cipher.DoFinal(bytes, length);

            return Convert.ToBase64String(bytes);
        }

        public static string Decrypt(string str)
        {
            var data = Convert.FromBase64String(str);

            cipher.Init(false, parametersWithIV);
            var bytes = new byte[cipher.GetOutputSize(data.Length)];
            var length = cipher.ProcessBytes(data, bytes, 0);
            cipher.DoFinal(bytes, length);

            return Encoding.UTF8.GetString(bytes);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var encryptedString = BouncyCastleRijndael.Encrypt("abc123");
            Console.WriteLine(encryptedString);
            // K7vBcS3Wbh2H7jGrXe4XfoLDGRDIOZ2zk9qqScpxzYU=

            var decryptedString = BouncyCastleRijndael.Decrypt(encryptedString);
            Console.WriteLine(decryptedString);
            // abc123
        }
    }
}

.NET Core HttpClientでproxyを利用する

Ⅰ. はじめに

.NET CoreではWebProxyクラスは存在しません。
代わりにIWebProxyを継承して自分でクラスを作る必要があります。

※2017/05/30 追記
.NET Core 2.0 でWebProxyクラスが追加されました。

Ⅱ. サンプル

class MyWebProxy : IWebProxy
{
  public ICredentials Credentials { get; set; }
  public Uri GetProxy(Uri destination) => new Uri("http://127.0.0.1:3128");
  public bool IsBypassed(Uri host) => false;
}
var handler = new HttpClientHandler();
handler.Proxy = new MyWebProxy();
handler.UseProxy = true;

// 証明書を全て信頼する
// handler.ServerCertificateCustomValidationCallback = delegate { return true; };

var client = new HttpClient(handler);

その他

ServerCertificateCustomValidationCallback について

このプロパティを変更すると
Linux / Unix環境で OpenSSL 関係のエラーが出る場合があります。

.NET Core AESで暗号化、複合する

Ⅰ. はじめに

Aesクラスを利用します。

.NET Core で IV 256bit を使う方法はこちら。
http://kagasu.hatenablog.com/entry/2017/01/04/213533

Ⅱ. Aesを利用した複合の例

public byte[] DecryptRijndael(byte[] bytes)
{
  Aes aes = Aes.Create();
  aes.Padding = PaddingMode.None;
  aes.Mode = CipherMode.CBC;

  using (var decryptor = aes.CreateDecryptor(key, iv))
  {
    return decryptor.TransformFinalBlock(bytes, 0, bytes.Length);
  }
}