将leet-speak转换为明文

Dan*_*anO 10 c# passwords

除了我在维基百科上读到的内容之外,我对L33t语言并不吝啬.

我确实需要在我们的密码强度验证工具中添加一个字典检查,因为leet-speak只会给密码破解过程增加一些微不足道的开销,我想在对照字典进行检查之前对输入进行de-leet-ify .

为了澄清这背后的原因:当需要在其密码中添加符号时,许多用户只需对常用字进行一些非常可预测的leet替换,以满足数字和符号包含要求.因为它是如此可预测,所以仅仅使用原始字典单词就会增加密码的实际复杂性.\编辑

不知道所有的规则,特别是像"W"这样的多字符替换,并且确定这是一个已被多次解决的问题,包括开源项目.

我正在寻找代码示例,但到目前为止还没有找到.如果它是C#代码将是一个奖励!,但任何共同语言的代码将有所帮助.

此外,有一个可扩展的方法会很好,因为据我所知,这种方言很快就会发展.随着这些规则的发展,能够在一年内添加一些规则会很高兴.

不,这不是我整个密码强度检查的基础.这只是我在这篇文章中寻求帮助的部分.因此,我们不会被密码和安全问题的其他元素分心,让我描述与leet-speak无关的密码问题:

我们根据NIST特殊出版物800-63测量密码中的熵位,并且需要策略可配置的等效测量(例如56位)以使密码有效.这仍然为词典单词提供了空间,这些单词已被简单地提出来,并且从熵的角度来看并不是更好的普通字典单词.

我只想告诉用户"P @ s5w0rd"太靠近字典单词了,他们可能会找到一个更强的密码.

我知道有很多更喜欢人们可以记住的密码,并且是安全的密码之间的平衡安全性的考虑.这不是那个问题.

我所要求的就是转换的l33t以明文这应该是几乎一样好玩有趣的话题作为代码高尔夫球.有没有人见过任何代码示例?

Fos*_*sco 13

我必须说我认为这是一个坏主意...如果你想让它们变得强大,那就提出更好的要求..必须至少8个字符,包含大写和小写字母,至少包含一个数字,至少一个特殊的角色.在禁用帐户之前实施最大授权失败计数器.一旦完成,你还担心什么?

  • 我不认为OP只对常见的1337字样感兴趣,比如h4x0r等,而且在密码中使用1337以符合他的规则.例如,如果我通常使用"escobar"作为我的密码,那么他将不允许"esc0b4r" - 好吧,至少那是我如何解释他的问题描述:) (5认同)
  • @Stephen即使那时OP的问题想要解决这个问题......他们会得到类似"leet haxxor"或"精英黑客"的东西,这取决于他们遵循的规则,他们最好将"l33t haxx0r"添加到词典中密码不好. (3认同)
  • +1为更好的方向,更相关的安全原则. (2认同)
  • @Jonathon:我同意你的看法.我只是指出这个答案并没有真正解决OP的问题 - 他已经在计划定义强密码要求. (2认同)
  • 谢谢大家.其中许多建议已在系统中生效,我没有提及它们,因为它们与问题并不十分相关.根据NIST关于该主题的出版物,我在熵比例方面有一个复杂性度量.密码必须至少等于56位(可由策略配置).但字典检查是一个重要的补充."P @ s5W0rd"可以通过简单的regex检查,甚至看起来不错熵,而是因为它是一本字典的字已leeted它增加了琐碎的开销为dicitonary攻击它不是一个好的密码. (2认同)

Fos*_*sco 10

还提供一些代码:

String password  = @"\/\/4573Fu|_";
Dictionary<string, string> leetRules = new Dictionary<string, string>();

leetRules.Add("4", "A");
leetRules.Add(@"/\", "A");
leetRules.Add("@", "A");
leetRules.Add("^", "A");

leetRules.Add("13", "B");
leetRules.Add("/3", "B");
leetRules.Add("|3", "B");
leetRules.Add("8", "B");

leetRules.Add("><", "X");

leetRules.Add("<", "C");
leetRules.Add("(", "C");

leetRules.Add("|)", "D");
leetRules.Add("|>", "D");

leetRules.Add("3", "E");

leetRules.Add("6", "G");

leetRules.Add("/-/", "H");
leetRules.Add("[-]", "H");
leetRules.Add("]-[", "H");

leetRules.Add("!", "I");

leetRules.Add("|_", "L");

leetRules.Add("_/", "J");
leetRules.Add("_|", "J");

leetRules.Add("1", "L");

leetRules.Add("0", "O");

leetRules.Add("5", "S");

leetRules.Add("7", "T");

leetRules.Add(@"\/\/", "W");
leetRules.Add(@"\/", "V");

leetRules.Add("2", "Z");

foreach (KeyValuePair<string,string> x in leetRules)
{
    password = password.Replace(x.Key, x.Value);
}

MessageBox.Show(password.ToUpper());
Run Code Online (Sandbox Code Playgroud)


Jas*_*yne 5

根据上面 Samy 的回答,这里有一个进一步增强的版本。它允许每个输入字符有多个输出规则,特别是为所有非字母数字字符设置了从字符串中删除的规则。结果就是你可以把Tr0ub4dor&3的经典XKCD漫画密码送出去Troubador。

我使用它的目的与 OP 大致相同,以确认提供给我的系统的包含高度安全数据的密码不是基于字典单词。

我正在获取 decode 函数的输出,并通过字典运行它。

  public class LeetSpeakDecoder
    {
        private Dictionary<string, IEnumerable<string>> Cache { get; set; }
        private Dictionary<string, List<string>> Rules  = new Dictionary<string, List<string>>();

        public void AddRule(string key, string value)
        {
            List<string> keyRules = null;
            if (Rules.ContainsKey(key))
            {
                keyRules = Rules[key];
            }
            else
            {
                keyRules = new List<string>();
                Rules[key] = keyRules;
            }
            keyRules.Add(value);
        }

        public LeetSpeakDecoder()
        {
            Cache = new Dictionary<string, IEnumerable<string>>();


            AddRule("4", "A");
            AddRule("4", "a");
           AddRule(@"/\", "A");
           AddRule("@", "A");
           AddRule("^", "A");
           AddRule("13", "B");
           AddRule("/3", "B");
           AddRule("|3", "B");
           AddRule("8", "B");
           AddRule("><", "X");
           AddRule("<", "C");
           AddRule("(", "C");
           AddRule("|)", "D");
           AddRule("|>", "D");
           AddRule("3", "E");
           AddRule("6", "G");
           AddRule("/-/", "H");
           AddRule("[-]", "H");
           AddRule("]-[", "H");
           AddRule("!", "I");
           AddRule("|_", "L");
           AddRule("_/", "J");
           AddRule("_|", "J");
           AddRule("1", "L");
           AddRule("0", "O");
           AddRule("0", "o");
           AddRule("5", "S");
           AddRule("7", "T");
           AddRule(@"\/\/", "W");
           AddRule(@"\/", "V");
           AddRule("2", "Z");

            const string nonAlpha = @"0123456789!@#$%^&*()-_=+[]{}\|;:'<,>./?""";
            foreach (var currentChar in nonAlpha)
            {
                AddRule(currentChar.ToString(), "");
            }
        }

        public IEnumerable<string> Decode(string leet)
        {
            var list = new List<string>();
            if (Cache.ContainsKey(leet))
            {
                return Cache[leet];
            }

            DecodeOneCharacter(leet, list);
            DecodeMoreThanOneCharacter(leet, list);
            DecodeWholeWord(leet, list);

            list = list.Distinct().ToList();

            Cache.Add(leet, list);
            return list;
        }

        private void DecodeOneCharacter(string leet, List<string> list)
        {
            if (leet.Length == 1)
            {
                list.Add(leet);
            }
        }

        private void DecodeMoreThanOneCharacter(string leet, List<string> list)
        {
            if (leet.Length > 1)
            {   // we split the word in two parts and check how many variations each part will decode to
                for (var splitPoint = 1; splitPoint < leet.Length; splitPoint++)
                {
                    foreach (var leftPartDecoded in Decode(leet.Substring(0, splitPoint)))
                    {
                        foreach (var rightPartDecoded in Decode(leet.Substring(splitPoint)))
                        {
                            list.Add(leftPartDecoded + rightPartDecoded);
                        }
                    }
                }
            }
        }

        private void DecodeWholeWord(string leet, List<string> list)
        {
            if (Rules.ContainsKey(leet))
            {
                foreach (var ruleValue in Rules[leet])
                {
                    list.Add(ruleValue);
                }

            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是我的输出

Tr0ub4dor&3
Tr0ub4dor&E
Tr0ub4dor&
Tr0ub4dor3
Tr0ub4dorE
Tr0ub4dor
Tr0ubAdor&3
Tr0ubAdor&E
Tr0ubAdor&
Tr0ubAdor3
Tr0ubAdorE
Tr0ubAdor
Tr0ubador&3
Tr0ubador&E
Tr0ubador&
Tr0ubador3
Tr0ubadorE
Tr0ubador
Tr0ubdor&3
Tr0ubdor&E
Tr0ubdor&
Tr0ubdor3
Tr0ubdorE
Tr0ubdor
TrOub4dor&3
TrOub4dor&E
TrOub4dor&
TrOub4dor3
TrOub4dorE
TrOub4dor
TrOubAdor&3
TrOubAdor&E
TrOubAdor&
TrOubAdor3
TrOubAdorE
TrOubAdor
TrOubador&3
TrOubador&E
TrOubador&
TrOubador3
TrOubadorE
TrOubador
TrOubdor&3
TrOubdor&E
TrOubdor&
TrOubdor3
TrOubdorE
TrOubdor
Troub4dor&3
Troub4dor&E
Troub4dor&
Troub4dor3
Troub4dorE
Troub4dor
TroubAdor&3
TroubAdor&E
TroubAdor&
TroubAdor3
TroubAdorE
TroubAdor
Troubador&3
Troubador&E
Troubador&
Troubador3
TroubadorE
Troubador
Troubdor&3
Troubdor&E
Troubdor&
Troubdor3
TroubdorE
Troubdor
Trub4dor&3
Trub4dor&E
Trub4dor&
Trub4dor3
Trub4dorE
Trub4dor
TrubAdor&3
TrubAdor&E
TrubAdor&
TrubAdor3
TrubAdorE
TrubAdor
Trubador&3
Trubador&E
Trubador&
Trubador3
TrubadorE
Trubador
Trubdor&3
Trubdor&E
Trubdor&
Trubdor3
TrubdorE
Trubdor
Run Code Online (Sandbox Code Playgroud)