买过火车票的都应该知道,身份证中间有四位为”*”,但是仔细一看其实那是我们的生日,当然了,就算我们的票转移到了别人的手里,你也一定会觉得我这生日那么多组合,肯定不可能猜出来,丢了丢了。。
那么问题来了,这四位*号到底能不能猜出来呢?
假设我们现在得到这张身份证,“4508211980xxxx2412”,下面我们来对这个星号进行破解~
最容易想到的就是日期的列举,当然这里我们为了提高效率,列举的时候也要考虑现实情况,下面我们开始对这个日期进行分析(假设“xxxx”现在为“abcd”)
首先a只能为1或0,当a为1的时候,b只能为0、1、2,a为0的时候,b为1-9
然后c只能为0、1、2、3,当c为0的时候,d只能为1-9,当c为1或2的时候,d的取值不限,当c为3的时候,d只能去0或1 ,一个月最大31号对吧。。。。。
在进行完上面的第一步分析,我们大概能得到12*31个日期,但是现实情况是分大小月,然后2月最多为28号,下面我们再对小月进行筛选,将小月的31号删去,将2月的29、30、31号删去,那么就会得到一个初步的符合实际情况的日期~
接下来是我们的重头戏,进行第二步筛选,其实这个算法早在15、16年就被人爆出来了,就是身份证上的最后一位为校验位,也就是说我们根据前17位,然后用一个算法可以计算出第18位,这样一来,我们可以利用算法排除那些明显不符合校验位的日期,实际证明这个算法排除了绝大多数的日期,最后能够符合实际并且通过算法验证的日期不过30多个。。。(代码会在最后贴出)
下面开始介绍这个神秘的身份证校验算法。。首先我们前17个数会有其固定的比例系数,然后每位数乘上这个比例系数,1-17位的比例系数位为7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2(数一数是不是17个),就拿这里的身份证举例,我也不举前17位那么多。。就举前四位(4508)为例子吧。。
按照上面的算法,前四位的累积和为4*7+5*9+0*10+8*5+……,后面还有13位,肯定用程序跑啊。。。
再计算完前17位的累积和之后,我们对其做模运算,简言之就是%11(除11看余数),这个余数由于模的特性,一定是0-10,因此又有一个对应关系,[‘1′,’0′,’X’, ‘9’, ‘8’, ‘7’, ‘6’, ‘5’, ‘4’, ‘3’, ‘2’],如果余数为0,那么校验和为‘1’,也就是说第18位为1,如果余数为1,那么对应过去即为‘0’,余数为2,对应过去为‘x’,以此类推。。终于知道为啥有人身份证最后一位为x了。。。
然后我们前面经过第一轮筛选得到了365个日期,也就对应了365个身份证,当然这里面只有一个是真实的,但是不止一个是正确的,请留意这句话,后面再分析。。
最后我们根据这个身份证校验算法可以排除那些明显不等于第18位校验和的身份证号码,留下那些符合实际且算法结果正确的身份证。。
这里我们截取了一部分最终留下来的身份证,其实数目相比先前的365个已经少很多了。。。然后我们随便拿一个身份证去身份证号查询网站去试试水。。
查到了,并且根据提示身份证号正确,但是这就是那独一无二的身份证?运气爆棚了?
其实不是,这些网站也是根据这个身份证校验算法来判断这个身份证是否正确,而不能判断这个身份证是否真实!这里的发证地、生日、性别其实在身份证里都有其固定的标志,因此我们需要其他途径来给查看这个身份证的实名制!来看看是不是真的叫光头强~
继续百度,会找到很多提供身份证接口查询的网站,但是这类网站都需要付费,笔者实在想验证一回,做好了付钱的准备,再准备查询的时候,突然提示我身份证查询服务只提供给认证企业。。。这也解释了为什么我们在注册账号时需要提供身份证号,而网站又是如何来验证我们的身份证的。。。都是通过类似的验证接口。
最后附上代码(python2.7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#-*-coding:utf-8-*-
#1.3.5.7.8.10.12 是月大 2月只有28天
#4,6,9,11
string=‘4508211980xxxx2412’
a,b,c,d=0,0,0,0
data=”
datalist=[]
fp=open(‘dataall.txt’,‘w’)
for a in range(0,2):
if a ==0:
for b in range(1,10):
for c in range(0,4):
if c==0:
for d in range(1,10):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
if c==1 or c==2:
for d in range(0,10):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
if c==3:
for d in range(0,2):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
if a==1:
for b in range(0,3):
for c in range(0,4):
if c==0:
for d in range(1,10):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
if c==1 or c==2:
for d in range(0,10):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
if c==3:
for d in range(0,2):
data=str(a)+str(b)+str(c)+str(d)
datalist.append(data)
#print datalist
datalist2=[]
for num in datalist:
if num[:2]==’02’:
if num[2:]==’29’ or num[2:]==’30’ or num[2:]==’31’:
num=‘0000’
datalist2.append(num)
#print num
if num[:2]==’04’ or num[:2]==’06’ or num[:2]==’09’ or num[:2]==’11’:
if num[2:]==’31’:
num=‘0000’
datalist2.append(num)
datalist2.append(num)
#print num
#print datalist2
for num in datalist2:
if num!=‘0000’:
fp.write(string.replace(‘xxxx’,num))
fp.write(‘n’)
fp.close()
ratio=[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
checksum=[‘1’,‘0’,‘X’, ‘9’, ‘8’, ‘7’, ‘6’, ‘5’, ‘4’, ‘3’, ‘2’]
fp=open(‘dataall.txt’,‘r’)
fp111=open(‘datafinal.txt’,‘w’)
for line in fp.readlines():
sum=0
line=line.strip()
for i in range(len(line)–1):
sum+=ratio[i]*int(line[i])
sum=sum%11
if checksum[sum]==line[–1]:
fp111.write(line)
fp111.write(‘n’)
fp111.close()
|
暑期有空参加了火种CTF的比赛,比赛总的来说不是很难,但是web部分遇到了很多困难,不过cryto较为简单,全部做出来了。逆向是一如既往的放弃,我要开始好好学逆向了~ 附比赛的wp: 传送门:火种CTF-wp 相关推荐: 利用java复现 ES文件浏览器 CV…
请登录后发表评论
注册