KeePass Password Safe 是一款优秀的密码管理工具,实际上可能还不仅仅是密码管理工具,重要的文件也可以保存在这款软件中。
现在说明一下其密码文件的结构
我们把其文件结构分成header(头部),body(主体)两部分来说明
Header:
PWM_DBSIG_1
PWM_DBSIG_2
PWM_FILE_VERS
HEADER_CIPHERID
HEADER_COMPRESSION
HEADER_MASTERSEED
HEADER_TRANSFORMSEED
HEADER_TRANSFORMROUNDS
HEADER_ENCRYPTIONIV
HEADER_STARTBYTES
HEADER_PROTECTEDKEY
HEADER_RANDOMSTREAMID
说明:
头部由如上各部分构成,每一部分具体说明:
PWM_DBSIG_1:
4个字节,用于DB标记,估计是大版本号值,其值为0x9AA2D903(小头表示)
PWM_DBSIG_2:
4个字节,用于DB标记,估计是小版本号值
2.07版值为0xB54BFB66(小头表示)
2.08版值为0xB54BFB67(小头表示)
PWM_FILE_VERS:
4个字节,用于文件版本标记
2.07版值为0x00010001
2.08版值为0x00010002
2.09版值为0x00020000
HEADER_CIPHERID:
共19个字节:
第一个字节:标示这个部分内容的编号,其值为2
2-3字节:内容长度,其值为16 (为小头表示)
16个字节:常数
HEADER_COMPRESSION:
共7个字节:
第一个字节:标示这个部分内容的编号,其值为3
2-3字节:内容长度,其值为4
4个字节:值为0x00000000或者0x00000001(都为小头表示),如果值为1,则表示body的内容块采用GZIP算法压缩,值为0表示没有采用GZIP算法压缩
HEADER_MASTERSEED:
共35个字节:
第一个字节:标示这个部分内容的编号,其值为4
2-3字节:内容长度,其值为32
32个字节:产生最后解码key的参数
HEADER_TRANSFORMSEED:
共35个字节:
第一个字节:标示这个部分内容的编号,其值为5
2-3字节:内容长度,其值为32
32个字节:产生TransformedKey的参数,具体细节见加解密说明
HEADER_TRANSFORMROUNDS:
共11个字节:
第一个字节:标示这个部分内容的编号,其值为6
2-3字节:内容长度,其值为8
8个字节:其值默认为6000,产生TransformedKey的加密次数,具体细节见加解密说明
HEADER_ENCRYPTIONIV:
共19个字节:
第一个字节:标示这个部分内容的编号,其值为7
2-3字节:内容长度,其值为16 (为小头表示)
16个字节:AES加解密用到的参数,具体细节见加解密说明
HEADER_STARTBYTES:
共35个字节:
第一个字节:标示这个部分内容的编号,其值为8
2-3字节:内容长度,其值为32
32个字节:判断解密是否正确的参数,如果此32个字节跟body解密以后的前32字节一致,说明解密成功。具体细节见加解密说明
HEADER_PROTECTEDKEY:
共35个字节:
第一个字节:标示这个部分内容的编号,其值为9
2-3字节:内容长度,其值为32
32个字节:body中某元素内容加解密用到的key
HEADER_RANDOMSTREAMID:
共7个字节:
第一个字节:标示这个部分内容的编号,其值为9
2-3字节:内容长度,其值为4
4个字节:body中某元素内容加解密用到的方法编号
Body:
Body通过AES/CBC/PKCS5加解密处理
加密之前或解密之后其明文结构:
streamStartBytes
内容块
相关说明:
streamStartBytes: 为32个字节,用于解密的快速判断,通过比对HEADER_STARTBYTES中的32字节来判断解密是否成功
内容块为一至多个,每个内容块结构如下:
Blockindex
Zip数据串的SHA256Digest值
Zip数据串的长度
Zip数据串
Zip数据串说明:
该数据串为GZIP算法压缩后的结果,其原始内容为XML格式
如果某元素属性是protect的话,该元素内容会先采用Salsa20等可逆算法加密再做base64处理
body的具体的加解密细节见下一篇文章说明