4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#を使って秘密鍵と公開鍵で暗号・復号

Posted at

題記の通り、C#を使用した暗号化・復号化の実装。

なるべく簡単に暗号化と復号化の機能を使いたいな、と思って実装してみた。

参考にしたのはMSの以下のサイト。
https://docs.microsoft.com/ja-jp/dotnet/standard/security/encrypting-data

環境はVS2019で .NET Core 3.1を使用。

イメージとしては、以下のようなやり取りを想定してコーディング。

(1) サーバーが秘密鍵と公開鍵を発行する。
(2) クライアントに文字列で公開鍵情報を渡す。
(3) クライアントは公開鍵情報を使ってデータを暗号化、サーバーに送付。
(4) サーバーは秘密鍵情報を使ってデータを復号。

証明書とか使えばいいのかもしれないが、そこら辺の知識はあまりないのでコードだけですべてを完結させたかった・・・・

ソースは以下。(クリックするとソースが表示されます)
namespace RsaConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            // 暗号化したい文字列をバイト配列に変換
            string encryptWord = "冷やし中華ァァ~";
            var encByte = Encoding.Unicode.GetBytes(encryptWord);

            // 秘密鍵と公開鍵を生成
            RSA rsa = RSA.Create();

            // 鍵情報を保存
            var publicKey = rsa.ToXmlString(false);
            var privateKey = rsa.ToXmlString(true);

            // 公開鍵情報の文字列からオブジェクトを復元
            byte[] encryptedByte;
            using (RSA encRsa = RSA.Create())
            {
                encRsa.FromXmlString(publicKey);
                encryptedByte = encRsa.Encrypt(encByte, RSAEncryptionPadding.Pkcs1);
            }

            // 暗号化したバイトデータを16進数文字列に変換
            var encByteToString = BitConverter.ToString(encryptedByte);
            Console.WriteLine($"Encrypt: {encByteToString}");

            // 
            // 上記の方法で生成された16進数文字列を外部から受信したと仮定して、
            // 秘密鍵を使って復元する
            //

            // 送信されてきた文字列をバイト配列に変換
            var encStrToBytes = encByteToString.Split('-').Select(r => Convert.ToByte(r, 16)).ToArray();
            byte[] decryptedByte;

            // 秘密鍵情報の文字列からオブジェクトを復元し、復号
            using (RSA decRsa = RSA.Create())
            {
                decRsa.FromXmlString(privateKey);
                decryptedByte = decRsa.Decrypt(encStrToBytes, RSAEncryptionPadding.Pkcs1);
            }

            var decryptedString = Encoding.Unicode.GetString(decryptedByte);

            Console.WriteLine($"Decrypt: {decryptedString}");

            // 試しにテキトーな鍵で復号してみる
            var invalidDec = string.Empty;
            try
            {
                using (RSA invalidRsa = RSA.Create())
                {
                    decryptedByte = invalidRsa.Decrypt(encStrToBytes, RSAEncryptionPadding.Pkcs1);
                }
            }
            catch
            {
                Console.WriteLine("Failed to decrypt.");
            }

            return;
        }
    }
}

出力はこんな感じ。

Encrypt: 6F-5B-B7-F8-3D-C9-00-23-BE-84-29-82-56-7E-BE-7B-79-E8-BB-5F-76-2B-03-A8-49-1C-76-FB-49-56-04-1E-8A-CA-AD-5C-57-F7-21-CC-17-FE-04-C8-FD-F9-D5-0D-7B-2B-2B-3A-34-A0-AE-5D-82-D3-1E-78-55-22-06-DB-C2-AA-99-A8-D1-52-6A-27-0F-A6-86-D9-CA-DA-78-6F-00-D2-6C-1C-51-F2-88-FA-CC-F8-CD-B0-0D-8E-D1-55-89-53-43-4A-92-25-DD-13-55-8E-F4-95-5D-6E-B3-95-89-3A-DE-6A-A1-A5-89-A9-1F-3F-30-6A-04-D0-B0-4E-CF-CA-6E-03-D9-D7-30-2C-48-31-8A-34-4F-0D-5E-1A-19-CF-61-52-A0-AB-20-C0-69-B6-DE-CE-C7-6C-59-C4-C0-64-2A-05-7B-07-96-A0-77-DD-F3-5E-D0-1C-E8-76-3D-A7-6B-51-8C-BC-50-A9-9D-03-31-1C-36-97-DB-F8-63-55-4F-2C-85-FA-C0-03-C6-C8-BE-93-11-DA-67-CD-55-3E-E0-D3-BC-13-FF-26-FD-A6-F2-87-5E-31-01-C0-4C-9D-6F-6A-45-8F-34-A5-07-6B-C3-A7-19-48-77-89-4E-9F-A5-9C-F2-61-83-CE-3E-66-59-47-56-10-F3-03
Decrypt: 冷やし中華ァァ~
Failed to decrypt.

ちゃんと復号できてるし、テキトーな鍵じゃ復号できてませんね(当たり前か)

あとは、メッセージのハッシュ送付とかも一緒にやれば、通信相手の検証もまとめてできるということか~。
そこまでやればまぁまぁ安全ですね~。

以上!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?