比较C#和ColdFusion(CFMX_COMPAT)之间的密码哈希值

czu*_*ski 6 c# security coldfusion cryptography

我有一个密码哈希存储在一个表中,并通过以下coldfusion脚本放在那里 -

#Hash(Encrypt(Form.UserPassword,GetSiteVars.EnCode))#
Run Code Online (Sandbox Code Playgroud)

我想在ac#应用程序中添加一些外部功能.我希望能够利用已存在的数据,以便我可以对用户进行身份验证.有谁知道如何在c#中复制上面的coldfusion代码?

谢谢你的任何想法.

Sei*_*bar 10

我通过评论中提到的其他人查看了Railo代码.

以下是从Railo Java源移植到C#的CFMX_Compat.请参阅下面的使用示例.

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace RailoUtil
{
    // SOURCE: Railo Source Code License LGPL v2
    // http://wiki.getrailo.org/wiki/RailoLicense
    public class RailoCFMXCompat
    {
        private String m_Key;
        private int m_LFSR_A = 0x13579bdf;
        private int m_LFSR_B = 0x2468ace0;
        private int m_LFSR_C = unchecked((int)0xfdb97531);
        private int m_Mask_A = unchecked((int)0x80000062);
        private int m_Mask_B = 0x40000020;
        private int m_Mask_C = 0x10000002;
        private int m_Rot0_A = 0x7fffffff;
        private int m_Rot0_B = 0x3fffffff;
        private int m_Rot0_C = 0xfffffff;
        private int m_Rot1_A = unchecked((int)0x80000000);
        private int m_Rot1_B = unchecked((int)0xc0000000);
        private int m_Rot1_C = unchecked((int)0xf0000000);

        public byte[] transformString(String key, byte[] inBytes)
        {
            setKey(key);
            int length = inBytes.Length;
            byte[] outBytes = new byte[length];
            for (int i = 0; i < length; i++)
            {
                outBytes[i] = transformByte(inBytes[i]);
            }
            return outBytes;
        }

        private byte transformByte(byte target)
        {
            byte crypto = 0;
            int b = m_LFSR_B & 1;
            int c = m_LFSR_C & 1;
            for (int i = 0; i < 8; i++)
            {
                if (0 != (m_LFSR_A & 1))
                {
                    m_LFSR_A = m_LFSR_A ^ m_Mask_A >> 1 | m_Rot1_A;
                    if (0 != (m_LFSR_B & 1))
                    {
                        m_LFSR_B = m_LFSR_B ^ m_Mask_B >> 1 | m_Rot1_B;
                        b = 1;
                    }
                    else
                    {
                        m_LFSR_B = m_LFSR_B >> 1 & m_Rot0_B;
                        b = 0;
                    }
                }
                else
                {
                    m_LFSR_A = (m_LFSR_A >> 1) & m_Rot0_A;
                    if (0 != (m_LFSR_C & 1))
                    {
                        m_LFSR_C = m_LFSR_C ^ m_Mask_C >> 1 | m_Rot1_C;
                        c = 1;
                    }
                    else
                    {
                        m_LFSR_C = m_LFSR_C >> 1 & m_Rot0_C;
                        c = 0;
                    }
                }

                crypto = (byte)(crypto << 1 | b ^ c);
            }

            target ^= crypto;
            return target;
        }

        private void setKey(String key)
        {
            int i = 0;
            m_Key = key;
            if (String.IsNullOrEmpty(key)) key = "Default Seed";
            char[] Seed = new char[key.Length >= 12 ? key.Length : 12];
            Array.Copy(m_Key.ToCharArray(), Seed, m_Key.Length);
            int originalLength = m_Key.Length;
            for (i = 0; originalLength + i < 12; i++)
                Seed[originalLength + i] = Seed[i];

            for (i = 0; i < 4; i++)
            {
                m_LFSR_A = (m_LFSR_A <<= 8) | Seed[i + 4];
                m_LFSR_B = (m_LFSR_B <<= 8) | Seed[i + 4];
                m_LFSR_C = (m_LFSR_C <<= 8) | Seed[i + 4];
            }
            if (0 == m_LFSR_A) m_LFSR_A = 0x13579bdf;
            if (0 == m_LFSR_B) m_LFSR_B = 0x2468ace0;
            if (0 == m_LFSR_C) m_LFSR_C = unchecked((int)0xfdb97531);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

下面是对加密文本进行十六进制编码的用法示例,然后解密相同的内容.

RailoCFMXCompat cfmx = new RailoCFMXCompat();
UTF8Encoding encoding = new UTF8Encoding();

//encrypt my string
byte[] encrypted = cfmx.transformString("mySecretKey", encoding.GetBytes("clear text"));
string encryptedHex = BitConverter.ToString(encrypted); //72-07-AA-1B-89-CB-01-96-4F-51

//decrypt my string
byte[] encryptedBytes = HexToBytes("72-07-AA-1B-89-CB-01-96-4F-51");
byte[] decrypted = cfmx.transformString("mySecretKey", encryptedBytes);
string cleartext = encoding.GetString(decrypted);
Run Code Online (Sandbox Code Playgroud)


Ada*_*tle 2

我将在下面留下原始答案内容以供历史参考,但应该注意的是,这不是原始问题的有效答案

相反,请参阅 @Terrapin 在 2011 年 1 月发表的该帖子中得票最高的答案。我希望 OP 看到这一点并可以更改已接受的答案。哎呀,我什至会标记模组,看看是否可以对此采取任何措施。


为了建立在爱德华史密斯的答案和czuroski的后续评论的基础上,这是我的解决方案。

首先,您需要 C# 中的 XOR 函数,我从此处获取该函数并稍加修改。

using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleXOREncryption
{    
    public static class EncryptorDecryptor
    {
        public static string EncryptDecrypt(string textToEncrypt, int key)
        {            
            StringBuilder inSb = new StringBuilder(textToEncrypt);
            StringBuilder outSb = new StringBuilder(textToEncrypt.Length);
            char c;
            for (int i = 0; i < textToEncrypt.Length; i++)
            {
                c = inSb[i];
                c = (char)(c ^ key);
                outSb.Append(c);
            }
            return outSb.ToString();
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,获取 XOR 的结果并对其进行 base-64 编码。获得该字符串后,对其进行 MD5 哈希处理。结果应该与原始代码片段的结果匹配:

#Hash(Encrypt(Form.UserPassword,GetSiteVars.EnCode))#
Run Code Online (Sandbox Code Playgroud)

  • 如果您确实必须这样做,请查看 Railo 源代码(和许可信息)。它具有 CFMX_COMPAT 算法,您可以将其移植到 C#。 (2认同)
  • 对于任何阅读的人,我通过离线电子邮件与 czuroski 联系,我们确实得到了 Railo 类的 C# 端口。 (2认同)