【2025 能源网络安全大赛】数据安全赛道

Uncategorized
6.2k words

EnergyGroup-DataSecurity-dataIntegrityVerification

题目介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
给定一个Excel 文件《data.xlsx》,其中包含多个数据列,每一列的数据代表某一类记录。

文件中的数据可能在传输、存储或处理的过程中发生了丢失或篡改。

参赛选手需要对文件中的数据进行完整性校验,识别哪些列中的数据存在完整性问题,并输出校验结果。

A列B列的数据在文件生成时有对应的一列校验和(Checksum)数据。参赛选手需要根据原始数据列计算校验和,并与文件中的校验和列进行比较。

如果两者不一致,则认为该行的数据存在完整性问题。

参赛选手需要根据校验列推导使用的校验算法并编写程序对数据进行校验,并输出识别结果。输出格式“A列-不匹配的行数;B列-不匹配的行数”。

请参赛选手编写程序对《data.xlsx》中的A列B列数据进行完整性校验,构造上述格式的答案,并将答案的 MD5 值(MD5 值英文字符全小写,长度 32 个字符;计算答案的 MD5 值时,用 UTF-8 字符编码)提交至平台。

正确答案示例:A列-30;B列-40,提交结果示例:4d1c5c9b4757f2ff5d453b375c18254b

详细见题目附件

wp

这题难点在于题目是统计AB错误的总行数,而不是每列的每一个错误行。

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
import pandas as pd
import hashlib


info = pd.read_excel("./data.xlsx")


def check_sum(Ainfo,Asign):
# print(hashlib.sha512(Ainfo.encode("utf-8")).hexdigest())
if hashlib.sha256(Ainfo.encode("utf-8")).hexdigest() == Asign:
return True
if hashlib.sha512(Ainfo.encode("utf-8")).hexdigest() == Asign:
return True
if hashlib.md5(Ainfo.encode("utf-8")).hexdigest() == Asign:
return True
return False

final = []
An = Bn = 0


for idx,row in info.iterrows():
Aflag = None
Bflag = None
A = row["A列"]
B = row["B列"]
Acheck = row["A列校验和"]
Bcheck = row["B列校验和"]
if Aflag:=check_sum(A,Acheck)== False:
An +=1
if Bflag:=check_sum(B,Bcheck)== False:
Bn +=1

print(hashlib.md5(f"A列-{An};B列-{Bn}".encode("utf-8")).hexdigest())
# print(";".join(final))

Socialgroup-DataSecurity-dataEncryption

题目介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
给定一个包含敏感信息的文件《data.xlsx》,文件中有多个数据列,每列代表不同的敏感数据类型,如手机号、身份证号码、银行卡号和邮箱等。参赛选手需要对文件中的每一个数据进行加密处理,并输出加密后的数据。

数据加密应使用对称加密算法 AES (Advanced Encryption Standard),采用CBC模式并应用自定义填充方式(见下文),加密后的结果应以16进制字符串的形式保存。

参赛选手需要使用给定的密钥和初始iv,并使用该密钥对每个数据进行加密。加密后的数据最后按先行后列顺序拼接计算md5。

自定义填充方案:

第一层:数据长度字节:在填充开始部分添加表示原始数据长度的字节数。

第二层:固定字节序列:使用固定字节序列0xBB以增加填充的层次。

第三层:填充长度字节:填充内容的末尾添加表示填充长度的字节。

取舍:若只缺少一位填充,则只填充第一层,若只缺少两位填充,则只填充第一层第三层。

例子:块大小为16,当前值为11,填充内容:0x0b+0xBB*3+0x5

数据AES加密的密钥为:b'0123456789abcdef',初始IV为:b'abcdef0987654321'。

详细见题目附件

wp

唯一考点就是AES加密的应用,注意不要把AES定义成全局的,因为重复使用的情况下IV会变,题目没有要求IV要随着数据一起变化。

结果是要求先行后列的所有加密值拼接md5,所以这里用个嵌套for来+=处理即可,这里用到pandas的columns来取每行xlsx的headname。

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import hashlib
import pandas as pd


fileinfo = pd.read_excel("./data.xlsx",dtype=str)


def pendfunc(datainfo):
pad_num = 16 - (len(datainfo) % 16)
pad_data_len = pad_num - 2
if pad_num == 1 or pad_num == 2:
pad_data_len = 0
if pad_num == 16:
pad_num = 0
return pad_num,pad_data_len

def info_parse(datainfo):
datainfo_padnum, datainfo_pad_datalen = pendfunc(datainfo)
final_data = ""
if datainfo_padnum > 2:
final_data = datainfo.encode("utf-8") + len(datainfo).to_bytes(1, 'big') + (datainfo_pad_datalen * b'\xBB') + bytes([datainfo_padnum])
if datainfo_padnum == 2:
final_data = datainfo.encode("utf-8") + len(datainfo).to_bytes(1, 'big') + bytes([datainfo_padnum])
if datainfo_padnum == 1:
final_data = datainfo.encode("utf-8") + len(datainfo).to_bytes(1, 'big')
if datainfo_padnum == 0:
final_data = datainfo.encode("utf-8")
return final_data

final = []

bak_fileinfo = fileinfo.copy()

def Aes_CBCenc(info):
ciper = AES.new(b'0123456789abcdef',AES.MODE_CBC,b'abcdef0987654321')
return ciper.encrypt(info).hex()

new_xlx = pd.DataFrame(columns=["手机号","身份证号","银行卡号","邮箱"])



new_xlx["手机号"] = bak_fileinfo["手机号"].apply(lambda x: Aes_CBCenc(info_parse(x)) )
new_xlx["身份证号"] = bak_fileinfo["身份证号"].apply(lambda x: Aes_CBCenc(info_parse(x)) )
new_xlx["银行卡号"] = bak_fileinfo["银行卡号"].apply(lambda x: Aes_CBCenc(info_parse(x)))
new_xlx["邮箱"] = bak_fileinfo["邮箱"].apply(lambda x: Aes_CBCenc(info_parse(x)) )

final_str = ""

for idx,row in new_xlx.iterrows():
for i in new_xlx.columns:
final_str+=row[i]

print(hashlib.md5(final_str.encode("utf-8")).hexdigest())

flag

1c26cd85fbe28858f1b7428d7d57f5d6

Socialgroup-DataSecurity-dataDesensitization

题目介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
为了抵抗黑客攻击导致数据拖库等问题,需要将敏感数据识别并脱敏存储成⼀个表。给定脱敏算法逻辑,要求选⼿⽣成脱敏后的数据表数据(所有数据均为随机⽣成,与现实世界⽆任何联系)。为了防⽌⼀些隐私数据泄漏,现需要对该数据表进⾏脱敏操作,请按照指定要求对各字段进⾏脱敏处理,并按照先行后列拼接字符串(不包含标题行),对此字符串进行md5计算,得到答案。

脱敏要求:

编号:⽆需脱敏。

姓名:⼆字姓名对最后⼀位字使⽤ * 进⾏替换,三字姓名对中间⼀位字使⽤ * 进⾏替换,四字姓名对中间两位字使⽤ * 进⾏替换。

手机号:请对中间五位信息使⽤ * 进⾏替换。

身份证号码:请对除了前6位信息使⽤ * 进⾏替换。

银⾏卡:请对前四位和后十位信息使⽤ * 进⾏替换。

Email:请对字符 @ 前除 . 外的字符使⽤ * 进⾏替换。

性别:替换成未知。

微信号:请对为字符的信息使用 * 进行替换。

wp

这题难点在微信号的字符替换他说的太模糊了,所以可能是数字和字符也可能是所有字符包含特殊字符,也可能是单纯字母字符,比如这里我就用的字母字符

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
import pandas as pd
import re
import hashlib

fileinfo = pd.read_excel("./data.xlsx",dtype=str)

def username_parse(username):
username_len = len(username)
if username_len == 2:
return username[0] + "*"
if username_len == 3:
return username[0] + "*" + username[-1]
if username_len == 4:
return username[0] + "*"+ "*"+ username[-1]

def phone_parse(num):
return num[:3]+("*"*5)+num[-3:]

def sfz_parse(sfz):
return sfz[:6]+(len(sfz[6:])*"*")

def bank_parse(num):
plain_len = len(num) - 14
return ("*"*4)+num[4:plain_len+4] + (10*"*")

def mail_parse(mail):
splist = mail.split("@")
final_mail = re.sub(r"[^.]","*",splist[0])
return final_mail+"@"+splist[1]

def sex_parse(sex):
return "未知"


def wx_parse(wx):
return re.sub(r"[a-zA-Z]","*",wx)

newfile = fileinfo.copy()


newfile["姓名"] = newfile["姓名"].apply(lambda x:username_parse(x))
newfile["手机号"] = newfile["手机号"].apply(lambda x:phone_parse(x))
newfile["身份证号"] = newfile["身份证号"].apply(lambda x:sfz_parse(x))
newfile["银行卡号"] = newfile["银行卡号"].apply(lambda x:bank_parse(x))
newfile["Email"] = newfile["Email"].apply(lambda x:mail_parse(x))
newfile["性别"] = newfile["性别"].apply(lambda x:sex_parse(x))
newfile["微信号"] = newfile["微信号"].apply(lambda x:wx_parse(x))

final= ""

for idx,row in newfile.iterrows():
for col in newfile.columns:
final+=row[col]

print(hashlib.md5(final.encode("utf-8")).hexdigest())

flag

b1c27322797d01bb44e5709fbf2e4f02