GitHub
C#
Unity
セキュリティ
暗号

Unity(C#) で「正しい」暗号化処理をするライブラリを作成しました

概要

Unity(C#)において、共通鍵暗号の代表格であるAES暗号(正確にはAES暗号ではなくRijndael暗号)公開鍵暗号の代表格であるRSA暗号、それぞれ手軽に実装でき、セキュアな(解読されづらい)ものになるようにしたライブラリを公開しました。
UnityCipher
よかったら使ってください!!

使い方

詳しい使い方はUnityCipher/Examples/ 以下にサンプルがあるますので、こちらも確認して見てください。

また、ライブラリのメソッドを使う場合以下のようにusing UnityCipherを追加することで使用することができます。

using UnityCipher;

AES暗号を用いる場合

暗号化

以下のようなメソッドを呼び出すことで暗号化することができます。

var encrypted = RijndaelEncryption.Encrypt(planeText, passwordText);

こうすることで暗号化されたもの(encrypted)を取得することができます。
Encryptメソッドの第一引数である、planeTextはbyte[]を指定することもでき、この場合、暗号化されたbyte[]を受け取ります。

復号

以下のようなメソッドを呼び出すことで復号することができます。

var planeText = RijndaelEncryption.Decrypt(encryptedText, passwordText);

暗号化されたものをうまく復号できれば復号されたもの(planeText)を取得することができます。
Decryptメソッドの第一引数である、encryptedTextには暗号化されたbyte[]を指定することもでき、この場合、うまく復号できれば復号されたされたbyte[]を受け取ります。

RSA暗号を用いる場合

公開鍵と秘密鍵のペアの作成

まずは以下のようなメソッドを呼び出すことで公開鍵と秘密鍵をそれぞれ作成します。

KeyValuePair<string, string> publicAndPrivateKeyValuePair = RSAEncryption.GenrateKeyPair(int keySize);

このとき、引数に設定したkeySizeに設定した値の大きさの公開鍵、秘密鍵が生成されます。指定できるkeySizeの値は512~16384の間の8bit単位での数字(8の倍数)になります。
詳しくはこちらを参照してください。
RSACryptoServiceProvider.KeySize Property
ここで指定する値が大きくなればなるほど、生成される公開鍵、秘密鍵の長さが大きくなり、よりセキュアなものになりますが、同時に暗号化、復号の処理負荷も上がります。
生成された公開鍵、秘密鍵はKeyValuePair<string, string>の形(publicAndPrivateKeyValuePair)で取得でき、それぞれKeyが公開鍵、Valueが秘密鍵となります。

暗号化

以下のようなメソッドを呼び出すことで暗号化することができます。

var encrypted = RSAEncryption.Encrypt(planeText, publicKey);

上記で生成した公開鍵(publicKey)を第二引数に指定することでRSA暗号化された暗号文(encrypted)を取得することができます。
Encryptの第一引数である、planeTextはbyte[]を指定することもでき、この場合、暗号化されたbyte[]を受け取ります。

復号

以下のようなメソッドを呼び出すことで暗号化することができます。

var planeText = RSAEncryption.Decrypt(encryptedText, privateKey);

上記で生成した公開鍵(privateKey)を第二引数に指定することで、うまく復号できれば復号されたもの(planeText)を取得することができます。
Decryptの第一引数である、planeTextはbyte[]を指定することもでき、byte[]を指定することもでき、この場合、うまく復号できれば復号されたされたbyte[]を受け取ります。

特徴

このライブラリの特徴として

  • 「使い方」のようにシンプルに使うことができる。
  • 共通鍵暗号では同じ平文、同じパスワードであっても、暗号化するたびに暗号文が変わるので、暗号鍵が推測されづらい。(セキュア)

というのがあります。
なお、RSA暗号はスタンダードなものを使用しているため、今回、詳しい話は省略します。

よくある話

AES暗号を実装する場合、平文、パスワード、ソルト(Salt)、IV(初期ベクター)という4種類の要素を設定する必要があります。そして、SaltとIVを固定の決まった値に設定されてしまうことが非常によくあります。しかし、本来、AES暗号のコンセプト(特徴)として、「同じ平文、同じパスワードであっても、暗号化するたびに暗号文が変わる」という特徴があるのですが、IVとソルトが固定値だとこの特徴をが適用されません。(同じ平文、同じパスワードだと毎回同じ暗号文になる)
本来のAES暗号の特徴はSaltとIVを生成すると毎回異なる値が生成されることにより、実現されています。しかし、実際の運用において、SaltとIVを固定して用いられる場合が非常に多くあります。

仕様

今回のライブラリでは、AES暗号においては、毎回、SaltとIVを生成しています。Salt + IV + 暗号文を組み合わせた結果を暗号文として生成しています。(詳しくはこちら)
これにより、「同じ平文、同じパスワードであっても、暗号化するたびに暗号文が変わる」ようにしています。
なお、現存の仕様は公開したため、よりセキュアに運用したい場合、順番を変えたり、bitの組み合わせを変えるなどの独自ルールにすることで対応することもできると思います。

参考・関連