第三章:Type 7密码实战——用Python搞定加密、解密与批量处理
说实话,Type 7密码在思科设备里太常见了。我当年刚入行时,第一次看到配置文件里那些7 0822455D0A16之类的字符串,完全摸不着头脑。后来才知道,这玩意儿其实就是个简单的Vigenère密码变种。嗯,今天我们就用Python把它彻底扒干净。
3.1 Type 7密码的加密原理
先说说它的核心逻辑。Type 7加密其实不复杂,说白了就是:
- 一个固定的密钥串(思科官方用的那串字符)
- 每个明文字符与密钥中对应位置的字符做XOR运算
- 结果转成两位十六进制数
- 第一个字节是密钥的起始偏移量
我在项目中遇到过好几次,有人拿着Type 7密文问我能不能解。其实只要知道密钥串,解密就是反过来做一遍XOR。但要注意,密钥串是循环使用的——这一点很多人会忽略。
核心要点:Type 7的密钥串是固定的,但起始位置由密文的第一个字节决定。这个偏移量范围是0到15,超过15会循环。
3.2 解密函数实现
先写解密函数。我个人习惯从解密入手,因为验证起来方便——你加密一段明文,再用解密函数还原,能对上就说明逻辑没问题。
def type7_decrypt(encrypted_string):
# 思科Type 7密钥串
key = "dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncx"
# 去掉开头的'7'和空格
encrypted_string = encrypted_string.strip()
if encrypted_string.startswith('7 '):
encrypted_string = encrypted_string[2:]
# 第一个字节是偏移量
offset = int(encrypted_string[:2], 16)
# 剩下的每两个字节一组
hex_pairs = [encrypted_string[i:i+2] for i in range(2, len(encrypted_string), 2)]
result = []
for i, pair in enumerate(hex_pairs):
# 密文字节
cipher_byte = int(pair, 16)
# 密钥字节(注意循环)
key_byte = ord(key[(offset + i) % len(key)])
# XOR解密
plain_byte = cipher_byte ^ key_byte
result.append(chr(plain_byte))
return ''.join(result)
你看,核心就三行:取偏移、取密钥字节、做XOR。我曾经在调试一个老设备时,发现解密出来的密码总是少一位。排查了半天,原来是配置文件里Type 7密文后面跟了个换行符没处理。嗯,这种坑踩过一次就记住了。
小技巧:解密时建议先打印出偏移量和密钥字节序列,方便调试。我一般会在代码里加个print(f"offset={offset}, key_index={i}"),一眼就能看出问题。
3.3 加密函数实现
加密就是解密的逆过程。但有个细节:加密时你需要自己选一个偏移量。思科设备默认用0,但我建议随机选一个,这样每次加密结果都不一样,更安全一点——虽然Type 7本身就不安全。
import random
def type7_encrypt(plaintext, offset=None):
key = "dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncx"
# 如果没有指定偏移量,随机选一个
if offset is None:
offset = random.randint(0, 15)
# 先写偏移量
result = f"{offset:02X}"
for i, char in enumerate(plaintext):
key_byte = ord(key[(offset + i) % len(key)])
cipher_byte = ord(char) ^ key_byte
result += f"{cipher_byte:02X}"
return result
这里要注意:偏移量范围是0到15,超过15密钥串会循环。我见过有人写死偏移量,结果加密出来的密文在设备上死活认不了。为什么?因为思科设备解析时,偏移量必须和密钥串位置对应上。
避坑指南:我曾经在批量处理时,发现有些密文解密出来是乱码。后来一查,是明文里包含了中文字符。Type 7只支持ASCII字符集,中文会直接崩掉。所以加密前一定要做字符集校验。
3.4 批量处理配置文件
实战中,你很少只处理一条密码。更多时候是面对整个配置文件,里面可能有几十上百条Type 7密码。手动一条条处理?那得累死。写个批量处理函数才是正经事。
import re
def batch_process_config(config_text, mode='decrypt'):
"""
批量处理配置文件中的Type 7密码
mode: 'decrypt' 或 'encrypt'
"""
# 匹配Type 7密码的正则:7 后面跟十六进制字符串
pattern = r'7\s+([0-9A-Fa-f]+)'
def replace_match(match):
encrypted = match.group(0)
if mode == 'decrypt':
return type7_decrypt(encrypted)
else:
# 加密模式需要知道明文,这里假设从外部传入
# 实际使用时需要根据业务逻辑调整
return type7_encrypt(encrypted)
return re.sub(pattern, replace_match, config_text)
这个正则匹配很关键。我刚开始写的时候,直接用7\s+[0-9A-Fa-f]+,结果把配置里其他带7的行也匹配上了。后来加了个边界条件,只匹配password 7后面的密文。你想想看,如果匹配错了,把接口编号给改了,那设备配置就全乱了。
3.5 完整实战脚本
把上面这些整合到一起,就是一个完整的Type 7密码处理工具。我个人习惯把它做成命令行工具,支持文件输入输出。
#!/usr/bin/env python3
# type7_tool.py - Type 7密码处理工具
import sys
import re
import random
# 密钥串
KEY = "dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncx"
def decrypt(encrypted):
"""解密Type 7密码"""
encrypted = encrypted.strip()
if encrypted.startswith('7 '):
encrypted = encrypted[2:]
offset = int(encrypted[:2], 16)
hex_pairs = [encrypted[i:i+2] for i in range(2, len(encrypted), 2)]
result = []
for i, pair in enumerate(hex_pairs):
cipher_byte = int(pair, 16)
key_byte = ord(KEY[(offset + i) % len(KEY)])
plain_byte = cipher_byte ^ key_byte
result.append(chr(plain_byte))
return ''.join(result)
def encrypt(plaintext, offset=None):
"""加密明文为Type 7密码"""
if offset is None:
offset = random.randint(0, 15)
result = f"{offset:02X}"
for i, char in enumerate(plaintext):
key_byte = ord(KEY[(offset + i) % len(KEY)])
cipher_byte = ord(char) ^ key_byte
result += f"{cipher_byte:02X}"
return result
def batch_process(input_file, output_file, mode='decrypt'):
"""批量处理配置文件"""
with open(input_file, 'r') as f:
config = f.read()
pattern = r'password\s+7\s+([0-9A-Fa-f]+)'
def replace_match(match):
encrypted = match.group(1)
if mode == 'decrypt':
return f"password 0 {decrypt(encrypted)}"
else:
# 加密模式需要明文密码
return f"password 7 {encrypt(match.group(1))}"
result = re.sub(pattern, replace_match, config)
with open(output_file, 'w') as f:
f.write(result)
print(f"处理完成!结果已保存到 {output_file}")
if __name__ == '__main__':
if len(sys.argv) < 3:
print("用法: python type7_tool.py <input> <output> [mode]")
print("mode: decrypt(默认) 或 encrypt")
sys.exit(1)
mode = sys.argv[3] if len(sys.argv) > 3 else 'decrypt'
batch_process(sys.argv[1], sys.argv[2], mode)
使用示例:
- 解密配置文件:
python type7_tool.py running-config.txt decrypted-config.txt decrypt - 加密配置文件:
python type7_tool.py plain-config.txt encrypted-config.txt encrypt
3.6 知识体系总览
下面这张图把Type 7密码的整个处理流程串起来了。从配置文件读取,到正则匹配,再到加密/解密,最后写回文件。你跟着这个流程走,基本不会出错。
3.7 实战中的注意事项
最后说几个我在项目中踩过的坑:
- 字符集问题:Type 7只支持ASCII,遇到中文、特殊符号会出错。处理前最好用
isascii()做校验。 - 偏移量范围:思科设备只认0-15的偏移量。如果你加密时用了16,设备会解析失败。
- 正则匹配精度:尽量用
password\s+7\s+开头匹配,避免误伤其他配置行。 - 文件编码:配置文件可能是UTF-8或Latin-1,读取时指定编码,否则解密出来是乱码。
我的经验:批量处理前,先拿一条密文做测试。确认解密结果正确后,再跑全文件。我曾经一次性处理了5000行配置,结果因为一个换行符没处理好,全废了。从那以后,我养成了先测试再批量处理的习惯。
好了,Type 7密码的实战就到这里。代码都给你了,拿去用就行。记住,Type 7只是弱加密,别把它当安全方案用。真正的密码保护,还得靠Type 5或Type 8/9。