題記の通り、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.
ちゃんと復号できてるし、テキトーな鍵じゃ復号できてませんね(当たり前か)
あとは、メッセージのハッシュ送付とかも一緒にやれば、通信相手の検証もまとめてできるということか~。
そこまでやればまぁまぁ安全ですね~。
以上!