文末附解密工具
密码样本
等长22位密码,CMD5可识别
GCV15/bVem29Cu9CiBpP+w GCV15/bVem29Cu9CiBpP+w E5Ia47UWnXs19vyWWsjKbg Q3GN6LRsX/ba1eJUEQqLeA Dhvt8khDDmpERqXcsUhtWQ
这是前5条数据, 长度都是22字节, 等长 → 目测应该是某种hash;
了解下这种加密是怎么来的, 走个流程熟悉熟悉,用第三条数据当示范:
E5Ia47UWnXs19vyWWsjKbg E5Ia47UWnXs19vyWWsjKbg==
密文长度为22, 22 mod 3 ≡ 1
, 补俩=
, 使其模3为0, 这就是base64;
不过有人会问, 长的像又不表示这就是base64,所以继续看看怎么把E5Ia47UWnXs19vyWWsjKbg
还原成出来:
先列个表,等会要用
00 | A | 16 | Q | 32 | g | 48 | w |
01 | B | 17 | R | 33 | h | 49 | x |
02 | C | 18 | S | 34 | i | 50 | y |
03 | D | 19 | T | 35 | j | 51 | z |
04 | E | 20 | U | 36 | k | 52 | 0 |
05 | F | 21 | V | 37 | l | 53 | 1 |
06 | G | 22 | W | 38 | m | 54 | 2 |
07 | H | 23 | X | 39 | n | 55 | 3 |
08 | I | 24 | Y | 40 | o | 56 | 4 |
09 | J | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
第一步把,E5Ia47UWnXs19vyWWsjKbg根据上面的表还原出来数值: 04 57 08 26 56 59 20 22 39 23 44 53 61 47 50 22
第二步,把04 57 08 26 56 59 20 22 39 23 44 53 61 47 50 22转成Bin值:
04 | 00000100 |
57 | 00111001 |
08 | 00001000 |
26 | 00011010 |
56 | 00111000 |
59 | 00111011 |
20 | 00010100 |
22 | 00010110 |
39 | 00100111 |
23 | 00010111 |
44 | 00101100 |
53 | 00110101 |
61 | 00111101 |
47 | 00101111 |
50 | 00110010 |
22 | 00010110 |
22 | 00010110 |
44 | 00101100 |
35 | 00100011 |
10 | 00001010 |
27 | 00011011 |
32 | 00100000 |
第三步,一共有22个, 前21个把开头的00去掉, 最后一个除了去掉开头的00还要去掉末尾的0000得到这个:
00010011 10010010 00011010 11100011 10110101 00010110 10011101 01111011 00110101 11110110 11111100 10010110 01011010 11001000 11001010 01101110
把Bin转换成Hex:
00010011 | 13 |
10010010 | 92 |
00011010 | 1A |
11100011 | E3 |
10110101 | B5 |
00010110 | 16 |
10011101 | 9D |
01111011 | 7B |
00110101 | 35 |
11110110 | F6 |
11111100 | FC |
10010110 | 96 |
01011010 | 5A |
11001000 | C8 |
11001010 | CA |
01101110 | 6E |
最后得到: 13921AE3B5169D7B35F6FC965AC8CA6E
,这种MD5(d_Base64)的方式在asp.net的Membership中自带了
internal string EncodePassword(string pass, int passwordFormat, string salt) { if (passwordFormat == 0) { return pass; } byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; byte[] inArray = null; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); if (passwordFormat == 1) { HashAlgorithm algorithm = HashAlgorithm.Create(Membership.HashAlgorithmType); if ((algorithm == null) && Membership.IsHashAlgorithmFromMembershipConfig) { RuntimeConfig.GetAppConfig().Membership.ThrowHashAlgorithmException(); } inArray = algorithm.ComputeHash(dst); } else { inArray = this.EncryptPassword(dst); } return Convert.ToBase64String(inArray);
主要思路是把密码字符串转换为字节数组存放,将salt(base64字符串)也转换为字节数组,将两者拼接着一个数组,然后对数组进行加密,当passwordformat为0时,返回原字符串,1或者其他的时候 则通过web.config中machinekey配置节中的Validation读取加密算法,可能算法是(MD5 SHA1 DES等)然后利用此加密算法对刚才的字符串进行加密,加密完后进行base64编码成字符串然后跟数据库中的密码进行比较,相同则登陆成功。如果数据中的salt值刚好为空时,还原回去的值才是原先的密码。
解密工具:d_Base64加密转32位MD5.exe