備忘録

備忘録

C# WPF 数値のみ入力できるTextBoxを作る

Ⅰ. はじめに

半角数値0~9のみを許可するTextBoxの作り方です。
数値のみ入力可能なTextBoxは標準機能として用意されていません。(2017/02/20時点)
入力値が数値かどうかを判定するコードを書く必要があります。

Ⅱ. 作り方

1. MainWindow.xaml

<TextBox
  x:Name="textBoxPrice"
  InputMethod.IsInputMethodEnabled="False"
  PreviewTextInput="textBoxPrice_PreviewTextInput"
  CommandManager.PreviewExecuted="textBoxPrice_PreviewExecuted"/>

2. MainWindow.xaml.cs

private void textBoxPrice_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
  // 0-9のみ
  e.Handled = !new Regex("[0-9]").IsMatch(e.Text);
}
private void textBoxPrice_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
  // 貼り付けを許可しない
  if (e.Command == ApplicationCommands.Paste)
  {
    e.Handled = true;
  }
}

C# で RSA暗号鍵(.pem)作成する

Ⅰ. はじめに

C#でpemファイルを作成する方法です。

その逆の、
C#でpemファイルを読み込む方法」はy_yoda様がQiitaに投稿している記事の通りです。
http://qiita.com/y_yoda/items/f4bd3ec56ac7591c5804

Ⅱ. 環境

  • C#
  • .NET Core 1.1.0

Ⅲ. ソースコード

NuGetで BouncyCastle をインストールして下さい。

Install-Package Portable.BouncyCastle

Program.cs

public class Program
{
  public static void Main(string[] args)
  {
    var rsa = RSA.Create();
    var parameter = rsa.ExportParameters(true);

    var privateKey = RsaPemMaker.GetPrivatePemString(parameter);
    File.WriteAllText("private-key.pem", privateKey);
    Console.WriteLine(privateKey);

    var publicKey = RsaPemMaker.GetPublicPemString(parameter);
    File.WriteAllText("public-key.pem", privateKey);
    Console.WriteLine(publicKey);

  }
}

RsaPemMaker.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;

public static class RsaPemMaker
{
  public static string GetPrivatePemString(RSAParameters p)
  {
    var key = new RsaPrivateCrtKeyParameters(
      new BigInteger(1, p.Modulus),
      new BigInteger(1, p.Exponent),
      new BigInteger(1, p.D),
      new BigInteger(1, p.P),
      new BigInteger(1, p.Q),
      new BigInteger(1, p.DP),
      new BigInteger(1, p.DQ),
      new BigInteger(1, p.InverseQ));

    using (var stream = new MemoryStream())
    {
      using (var writer = new StreamWriter(stream, new UTF8Encoding()))
      {
        var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(writer);
        pemWriter.WriteObject(key);
      }

      return new UTF8Encoding().GetString(stream.ToArray()).Replace("\r\n", "\n");
    }
  }

  public static string GetPublicPemString(RSAParameters p)
  {
    var key = new RsaKeyParameters(
      false,
      new BigInteger(1, p.Modulus),
      new BigInteger(1, p.Exponent));

    using (var stream = new MemoryStream())
    {
      using (var writer = new StreamWriter(stream, new UTF8Encoding()))
      {
        var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(writer);
        pemWriter.WriteObject(key);
      }

      return new UTF8Encoding().GetString(stream.ToArray()).Replace("\r\n", "\n");
    }
  }
}

Ⅲ. 実行結果

f:id:kagasu:20170202132705p:plain

メモ(2020/03/23 追記)

.NET 5でPEMの読み書きAPIが追加されるようです。
https://github.com/dotnet/runtime/pull/32260

C#でRSS 1.0のFeedを読む

Ⅰ. はじめに

.NET Framework 3.5以降であれば Atom 1.0 と RSS 2.0を対象にした SyndicationFeed があるのですが、RSS 1.0はサポートされていません。
RSS 1.0 を手書きで解析するときのメモです。

Ⅱ. プログラム

解析対象のXMLGIGAZINEのRSS1.0のFeedを利用しました)
https://gist.github.com/anonymous/19883bc8c892ca8f8ceaa5937257a83e

static void Main(string[] args)
{
  var xml = new XmlDocument();

  xml.Load("http://feed.rssad.jp/rss/gigazine/rss_1.0");

  var nsmgr = new XmlNamespaceManager(xml.NameTable);
  nsmgr.AddNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  nsmgr.AddNamespace("rss", "http://purl.org/rss/1.0/");
  nsmgr.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");

  foreach (XmlElement node in xml.SelectNodes("/rdf:RDF/rss:item", nsmgr))
  {
    var title = node.SelectNodes("rss:title", nsmgr)[0].InnerText;
    var link = node.SelectNodes("rss:link", nsmgr)[0].InnerText;
    var description = node.SelectNodes("rss:description", nsmgr)[0].InnerText;
    var date = DateTime.Parse(node.SelectNodes("dc:date", nsmgr)[0].InnerText);

    Console.WriteLine("-------");
    Console.WriteLine($"title: {title}");
    Console.WriteLine($"link: {link}");
    Console.WriteLine($"description: {description}");
    Console.WriteLine($"date: {date}");
  }
}

Ⅲ. 実行結果

f:id:kagasu:20170122230022p:plain

Nox App Player のデフォルトランチャーアプリを変更する方法

Ⅰ. はじめに

Nox App Playerでは、
Playストアから Nova Launcher などをインストールしても、
自動的にNox Launcherに切り替わってしまいます。
それを解決する方法です。

Ⅱ. やり方

1. NOXの設定でrootをONにする

2. 任意のランチャーアプリをインストールする。

3. ファイルマネージャを起動する

/system/app/launcher_1.6_en_signed.apk を
launcher_1.6_en_signed.apk.bak にリネームする
f:id:kagasu:20170105162256p:plain

4. Android設定→ホームでデフォルトを任意のランチャーアプリに設定する

以上

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
        }
    }
}