我正在尝试使用密码哈希系统(使用chap令牌进行密码哈希)将PHP和Javascript页面转换为C#。所以我有示例页面来显示步骤结果:
var myapp = angular.module('myapp', ['ui']);
myapp.controller('controller', function ($scope) {
$scope.list = ["one", "two", "thre", "four", "five", "six"];
});
angular.bootstrap(document, ['myapp']);
第一个警告显示字符串“M123456¼¢£i8£¬1”,所以在我的代码中我使用以下方式转换输入:
<?php
$chapid='\115';
$chapchallenge= '\274\013\242\243\236\226\151\224\070\023\243\207\252\061\016\254';
$pass = '123456';
?>
<script type="text/javascript">
<!--
alert('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>');
alert(((str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
alert((coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
alert(binl2hex(coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
//-->
</script>
/*
* Convert an 8-bit character string to a sequence of 16-word blocks, stored
* as an array, and append appropriate padding for MD4/5 calculation.
* If any of the characters are >255, the high byte is silently ignored.
*/
function str2binl(str)
{
var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++) blks[i] = 0
for(var i = 0; i < str.length; i++)
blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
blks[i>>2] |= 0x80 << ((i%4) * 8)
blks[nblk*16-2] = str.length * 8
return blks
}
接下来我必须将此字符串转换为字节(如public static string AsciiOctalToString(string ascii)
{
var list = ascii.Split('\\');
StringBuilder builder = new StringBuilder();
foreach (string octalPart in list.Where(x => x.Length > 0))
{
int i = Convert.ToInt32(octalPart, 8);
builder.Append(Convert.ToChar(i));
}
return builder.ToString();
}
),但它的格式有些奇怪。我不明白如何'将8位字符串转换为16字块的序列'。预期结果(来自警报2)为str2binl(str)
。我将{858927437, -1137298124, -1633443317, 949250454, -1433951469, -2136207823, 0, 0,0,0,0,0,0,0,184,0}
翻译为:
str2binl(str)
但我的结果与预期不同。
你知道我在做错了什么吗?
我为JavaScript代码添加了括号:
public static int[] Str2Binl(string str)
{
var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
var blks = new int[nblk*16];
for (var i = 0; i < str.Length; i++)
{
blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
blks[i >> 2] |= 0x80 << (i%4*8);
}
blks[nblk*16 - 2] = str.Length*8;
return blks;
}
但是行function str2binl(str)
{
var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
var blks = new Array(nblk * 16)
for(var i = 0; i < nblk * 16; i++)
{
blks[i] = 0
}
for(var i = 0; i < str.length; i++)
{
blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
}
blks[i>>2] |= 0x80 << ((i%4) * 8)
blks[nblk*16-2] = str.length * 8
return blks
}
也需要迭代器以及它在JS中的工作方式吗?
P.S。我不能在我的代码中使用这个JS库,我只需要哈希密码(它不是一个Web应用程序)。
答案 0 :(得分:1)
似乎问题是你在for
循环中放置了两行而不是只有一行。这有用吗?
public static int[] Str2Binl(string str)
{
var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
var blks = new int[nblk*16];
int i;
for (i = 0; i < str.Length; i++)
{
blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
}
blks[i >> 2] |= 0x80 << (i%4*8);
blks[nblk*16 - 2] = str.Length*8;
return blks;
}
无论如何,正如我已经评论过的那样,如果你真的关心安全性,你不应该自己进行散列,甚至不要使用MD5或SHA,而应该使用PBKDF2。除非由于某种原因你需要保留当前的算法。
另一方面,您的AsciiOctalToString
给了我不同的字符串:¼♂¢£??i?8‼£?ª1♫¬
。
where
(尽管你可能不喜欢它):
var list = ascii.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);