web-dev-qa-db-ja.com

.NETのパスワード暗号化/復号化コード

C#でパスワードの簡単な暗号化と復号化が必要です。パスワードを暗号化された形式でデータベースに保存し、復号化によって元の形式として取得する方法は?

25
kart

どうぞ。インターネットのどこかで見つけました。私にとってはうまくいきます。

    /// <summary>
    /// Encrypts a given password and returns the encrypted data
    /// as a base64 string.
    /// </summary>
    /// <param name="plainText">An unencrypted string that needs
    /// to be secured.</param>
    /// <returns>A base64 encoded string that represents the encrypted
    /// binary data.
    /// </returns>
    /// <remarks>This solution is not really secure as we are
    /// keeping strings in memory. If runtime protection is essential,
    /// <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="plainText"/>
    /// is a null reference.</exception>
    public string Encrypt(string plainText)
    {
        if (plainText == null) throw new ArgumentNullException("plainText");

        //encrypt data
        var data = Encoding.Unicode.GetBytes(plainText);
        byte[] encrypted = ProtectedData.Protect(data, null, Scope);

        //return as base64 string
        return Convert.ToBase64String(encrypted);
    }

    /// <summary>
    /// Decrypts a given string.
    /// </summary>
    /// <param name="cipher">A base64 encoded string that was created
    /// through the <see cref="Encrypt(string)"/> or
    /// <see cref="Encrypt(SecureString)"/> extension methods.</param>
    /// <returns>The decrypted string.</returns>
    /// <remarks>Keep in mind that the decrypted string remains in memory
    /// and makes your application vulnerable per se. If runtime protection
    /// is essential, <see cref="SecureString"/> should be used.</remarks>
    /// <exception cref="ArgumentNullException">If <paramref name="cipher"/>
    /// is a null reference.</exception>
    public string Decrypt(string cipher)
    {
        if (cipher == null) throw new ArgumentNullException("cipher");

        //parse base64 string
        byte[] data = Convert.FromBase64String(cipher);

        //decrypt data
        byte[] decrypted = ProtectedData.Unprotect(data, null, Scope);
        return Encoding.Unicode.GetString(decrypted);
    }
15

編集:これは非常に古い答えです。 SHA1は2011年に非推奨になりましたが、実際には壊れています。 https://shattered.io/ 代わりに新しい標準を使用します(SHA256、SHA512など)。

私のコメントの質問への答えが「いいえ」である場合、私が使用するものはここにあります:

    public static byte[] HashPassword(string password)
    {
        var provider = new SHA1CryptoServiceProvider();
        var encoding = new UnicodeEncoding();
        return provider.ComputeHash(encoding.GetBytes(password));
    }
11
Cogwheel

RC2CryptoServiceProviderを使用します。

    public static string EncryptText(string openText)
    {
        RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
        ICryptoTransform encryptor = rc2CSP.CreateEncryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv));
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                byte[] toEncrypt = Encoding.Unicode.GetBytes(openText);

                csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
                csEncrypt.FlushFinalBlock();

                byte[] encrypted = msEncrypt.ToArray();

                return Convert.ToBase64String(encrypted);
            }
        }
    }

    public static string DecryptText(string encryptedText)
    {
        RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
        ICryptoTransform decryptor = rc2CSP.CreateDecryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv));
        using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedText)))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                List<Byte> bytes = new List<byte>();
                int b;
                do
                {
                    b = csDecrypt.ReadByte();
                    if (b != -1)
                    {
                        bytes.Add(Convert.ToByte(b));
                    }

                }
                while (b != -1);

                return Encoding.Unicode.GetString(bytes.ToArray());
            }
        }
    }
4
Pavel Belousov

この質問は、暗号化/復号化の方法に答えます。 C#で文字列を暗号化および復号化しますか?

データベースを指定しませんでしたが、Convert.toBase64Stringを使用してbase-64エンコードしたいでしょう。たとえば、次を使用できます。 http://www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx

次に、暗号化されたメッセージの長さに応じて、varcharまたはblobに保存しますが、パスワードの場合はvarcharが機能します。

上記の例では、base64をデコードした後の復号化も取り上げます。

UPDATE:

実際には、base64エンコーディングを使用する必要はないかもしれませんが、印刷したりWebで送信したい場合に便利です。メッセージが十分に長い場合は、最初にメッセージを圧縮してから暗号化するのが最善です。メッセージが既にバイナリ形式である場合はブルートフォースを使用するのが難しいため、暗号化を正常に解除したことを判断するのは困難です。

3
James Black

最初に次のようなクラスを作成します。

public class Encryption
    { 
        public static string Encrypt(string clearText)
        {
            string EncryptionKey = "MAKV2SPBNI99212";
            byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(clearBytes, 0, clearBytes.Length);
                        cs.Close();
                    }
                    clearText = Convert.ToBase64String(ms.ToArray());
                }
            }
            return clearText;
        }

        public static string Decrypt(string cipherText)
        {
            string EncryptionKey = "MAKV2SPBNI99212";
            byte[] cipherBytes = Convert.FromBase64String(cipherText);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(cipherBytes, 0, cipherBytes.Length);
                        cs.Close();
                    }
                    cipherText = Encoding.Unicode.GetString(ms.ToArray());
                }
            }
            return cipherText;
        }
    }

**コントローラーで**

この暗号化クラスの参照を追加します。

using testdemo.Models

public ActionResult Index() {
            return View();
        }
        [HttpPost]
        public ActionResult Index(string text)
        {
            if (Request["txtEncrypt"] != null)
            {
                string getEncryptionCode = Request["txtEncrypt"];
                string DecryptCode = Encryption.Decrypt(HttpUtility.UrlDecode(getEncryptionCode));
                ViewBag.GetDecryptCode = DecryptCode;
                return View();
            }
            else {
                string getDecryptCode = Request["txtDecrypt"];
                string EncryptionCode = HttpUtility.UrlEncode(Encryption.Encrypt(getDecryptCode));
                ViewBag.GetEncryptionCode = EncryptionCode;
                return View();
            }

        }

表示中

<h2>Decryption Code</h2>
@using (Html.BeginForm())
{
    <table class="table-bordered table">
        <tr>
            <th>Encryption Code</th>
            <td><input type="text" id="txtEncrypt" name="txtEncrypt" placeholder="Enter Encryption Code" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <span style="color:red">@ViewBag.GetDecryptCode</span>
            </td>
        </tr>
        <tr>
                <td colspan="2">
                    <input type="submit" id="btnEncrypt" name="btnEncrypt"value="Decrypt to Encrypt code" />
                </td>
            </tr>
    </table>
}
    <br />
    <br />
    <br />
    <h2>Encryption Code</h2>
@using (Html.BeginForm())
{
    <table class="table-bordered table">
        <tr>
            <th>Decryption Code</th>
            <td><input type="text" id="txtDecrypt" name="txtDecrypt" placeholder="Enter Decryption Code" /></td>
        </tr>

        <tr>
            <td colspan="2">
                <span style="color:red">@ViewBag.GetEncryptionCode</span>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" id="btnDecryt" name="btnDecryt" value="Encrypt to Decrypt code" />
            </td>
        </tr>
    </table>
}
1
star test

暗号化の最も簡単な方法の1つ(.NETには既に[私の前にCogwheelが提供したような]すばらしい暗号化ライブラリがあるので絶対に自分で構成する必要がある場合)は、XOR ASCII既知の「キー」値に対する入力文字列の各文字の値。 C#のXOR機能は、^キーを使用して実現されます。

次に、値をXORの結果からASCII Charsに変換し、データベースに保存できます。これは安全性は高くありませんが、最も簡単な暗号化方法の1つです。

また、アクセスデータベースを使用している場合、文字列の前にいくつかの文字を入力すると、データベース自体を開くときにフィールド全体が読み取れなくなることがわかりました。ただし、悪意のあるユーザーにとっては空白であっても、フィールドはアプリで読み取り可能です。しかし、とにかくアクセスを使用する人はいますか?

0
Jrud

パスワードを暗号化/復号化しないでください。これは重大なセキュリティ上の脆弱性です。 PBKDF2、bcrypt、scrypts、またはArgonなどの強力なハッシュアルゴリズムを使用したHASHパスワード。

ユーザーがパスワードを設定したら、それをハッシュし、ハッシュ(およびソルト)を保存します。

ユーザーがログインしたら、提供されたパスワードを再ハッシュし、データベースのハッシュと比較します。

0
Jason Coyne
 string clearText = txtPassword.Text;
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
0
Jeet Poria