首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#中的md5(wordpress)密码加密

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

Stack Overflow用户
提问于 2015-12-07 14:30:41
回答 3查看 1.7K关注 0票数 6

我想从asp.net web应用程序中验证用户。应用程序使用的数据库是MySQL,数据库中存储的密码是从word press应用程序生成的加密格式。我需要加密的密码,以便我可以比较加密的密码与数据库密码。

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

如何在c#中生成此加密密码

EN

回答 3

Stack Overflow用户

发布于 2017-09-01 17:57:52

这花了我一段时间,但在这里你已经完成了从php到C#的几乎1:1的转换:

代码语言:javascript
复制
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

我有意省略了盐生成。但如果您将来需要它,它应该以$P$开头,长度至少为12个字符。使用这个额外的方法,你还可以散列新的密码,而不仅仅是检查散列是否正确。

票数 7
EN

Stack Overflow用户

发布于 2015-12-07 14:34:54

也许这对你有好处

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2021-03-22 08:38:42

我已经从class-phpass.php (参见你的wordpress安装的/wp-includes/class-phpass.php )重写了crypt_private php方法,以便在c#中使用。

​

​

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

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

如果你在带有wordpress的服务器上使用php5和更新的,这是可行的。

代码语言:javascript
复制
    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;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34127718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档