c#中的md5(wordpress)密码加密

时间:2015-12-07 06:30:41

标签: c# wordpress

我想验证用户表单asp.net Web应用程序。用于应用程序的数据库是MySQL,存储在db中的密码是加密格式,由word press应用程序生成。我需要加密密码,以便我可以将加密密码与数据库密码进行比较。

我的密码:按@ 123 加密密码:$ P $ BGW0cKLlkN6VlZ7OqRUvIY1Uvo / Bh9 /

如何在c#

中生成此加密密码

3 个答案:

答案 0 :(得分:3)

我花了一段时间,但在这里你几乎以1:1的比例从php转换为C#:

using System;
using System.Text;
using System.Security.Cryptography;
using System.Linq;

namespace WordpressHash {
    public class Program {
        private static string itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

        public static void Main(string[]args) {
            string StrPassword = "Push@123";
            string expected = "$P$BGW0cKLlkN6VlZ7OqRUvIY1Uvo/Bh9/";

            string computed = MD5Encode(StrPassword, expected);

            Console.WriteLine(StrPassword);
            Console.WriteLine(computed);
            Console.WriteLine("Are equal? " + expected.Equals(computed));
        }

        static string MD5Encode(string password, string hash) {
            string output = "*0";
            if (hash == null) {
                return output;
            }

            if (hash.StartsWith(output))
                output = "*1";

            string id = hash.Substring(0, 3);
            // We use "$P$", phpBB3 uses "$H$" for the same thing
            if (id != "$P$" && id != "$H$")
                return output;

            // get who many times will generate the hash
            int count_log2 = itoa64.IndexOf(hash[3]);
            if (count_log2 < 7 || count_log2 > 30)
                return output;

            int count = 1 << count_log2;

            string salt = hash.Substring(4, 8);
            if (salt.Length != 8)
                return output;

            byte[]hashBytes = {};
            using(MD5 md5Hash = MD5.Create()) {
                hashBytes = md5Hash.ComputeHash(Encoding.ASCII.GetBytes(salt + password));
                byte[]passBytes = Encoding.ASCII.GetBytes(password);
                do {
                    hashBytes = md5Hash.ComputeHash(hashBytes.Concat(passBytes).ToArray());
                } while (--count > 0);
            }

            output = hash.Substring(0, 12);
            string newHash = Encode64(hashBytes, 16);

            return output + newHash;
        }

        static string Encode64(byte[]input, int count) {
            StringBuilder sb = new StringBuilder();
            int i = 0;
            do {
                int value = (int)input[i++];
                sb.Append(itoa64[value & 0x3f]); // to uppercase
                if (i < count)
                    value = value | ((int)input[i] << 8);
                sb.Append(itoa64[(value >> 6) & 0x3f]);
                if (i++ >= count)
                    break;
                if (i < count)
                    value = value | ((int)input[i] << 16);
                sb.Append(itoa64[(value >> 12) & 0x3f]);
                if (i++ >= count)
                    break;
                sb.Append(itoa64[(value >> 18) & 0x3f]);
            } while (i < count);

            return sb.ToString();
        }
    }
}

数据库中的每个哈希都使用md5的salt和n次迭代进行编码。可在此处找到简要说明:https://codex.wordpress.org/Function_Reference/wp_hash_password

我有意无意生盐。但如果您将来需要它,它应该以{{1​​}}开头并且至少12个字符。使用这种额外的方法,您还可以散列新密码,而不仅仅是检查散列是否正确。

答案 1 :(得分:1)

可能这可能会为你做到这一点

using System.Security.Cryptography;

    class Program
    {
        static void Main(string[] args)
        {
            string StrPassword = "Push@123";
            using (MD5 md5Hash = MD5.Create())
            {
                string hashPassword = GetMd5Hash(md5Hash, StrPassword);
                Console.WriteLine(hashPassword);
            }
        }
        static string GetMd5Hash(MD5 md5Hash, string input)
        {
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }
    }

散列函数将任意长度的二进制字符串映射到固定长度的小二进制字符串。加密散列函数具有以下特性:找到散列到相同值的两个不同输入在计算上是不可行的;也就是说,如果相应的数据也匹配,则两组数据的哈希值应该匹配。对数据的微小更改会导致散列中出现大量不可预测的更改。

MD5算法的散列大小为128位。

MD5类的ComputeHash方法将散列作为16个字节的数组返回。请注意,某些MD5实现会生成32个字符的十六进制格式的哈希。要与此类实现进行互操作,请将ComputeHash方法的返回值格式化为十六进制值。

来源MSDN: MD5 Class

答案 2 :(得分:0)

我已经从 class-phpass.php 重写了 crypt_private php 方法(请参阅 /wp-includes/class-phpass.php 您的 wordpress 安装)来使用它在 C# 中。

enter image description here

密码是用户输入的字符串,设置是wp_users行的wp数据库中的user_pass值。

crypt_private 返回密码的哈希值。因此,如果 crypt_private 返回值等于设置值,则密码正确

如果您在带有 wordpress 的服务器上使用 php5 及更高版本,则此方法有效。

    private const string itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public bool SignIn(string password)
    {
        string foundUserHash = "hash from database (saved password of a user)";

        string hash = Crypt(password, foundUserHash);

        return foundUserHash == hash;
    }

    private string Crypt(string password, string setting)
    {


        string output = "*0";

        if (setting.Substring(0, 2) == output)
            output = "*1";

        string id = setting.Substring(0, 3);

        if (id != "$P$" && id != "$H$")
            return output;

        int count_log2 = itoa64.IndexOf(setting[3]);

        if (count_log2 < 7 || count_log2 > 30)
            return output;

        var count = 1 << count_log2;

        string salt = setting.Substring(4, 8);

        if (salt.Length != 8)
            return output;

        var hash = GetHash(
            GetByteArraysAppended(
                Encoding.UTF7.GetBytes(salt),
                Encoding.UTF7.GetBytes(password)
                ));
        
        do
        {
            hash = GetHash(
                GetByteArraysAppended(
                    hash, 
                    Encoding.UTF7.GetBytes(password)
                    ));
        }
        while (--count!=0);

        output = setting.Substring(0, 12);

        output += encode64(hash, 16);

        return output;
    }

    private string encode64(byte [] input, int count)
    {
        string output = "";
        int i = 0;

        do
        {
            Int32 value = input[i++];
            output += itoa64[value & 0x3f];

            if (i < count)
                value |= input[i] << 8;
            output += itoa64[(value >> 6) & 0x3f];
            if (i++ >= count)
                break;
            if (i < count)
                value |= input[i] << 16;
            output += itoa64[(value >> 12) & 0x3f];
            if (i++ >= count)
                break;
            output += itoa64[(value >> 18) & 0x3f];
        } while (i < count);

        return output;
    }



    private byte[] GetByteArraysAppended(byte[] partOne, byte[] partTwo)
    {
        var parts = partOne.ToList();
        parts.AddRange(partTwo);
        var result = parts.ToArray();

        return result;
    }

    private byte[] GetHash(byte [] bytesToHash)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        var hash = md5.ComputeHash(bytesToHash);

        return hash;
    }