android 备份文件 解析,Golang解析android 备份文件

我参考了一个stackoverflow上的一个项目,java解android备份文件。然后译成了golang代码。

总结:

java语言本身虽然很老,但是人家库多啊,但是人家的流还真是好用

想念java的第x天。

整体的备份文件:xx.ab 分为两部分

不加密部分

加密部分

分析

加密部分

我所解析的一个文件信息

magic string

version int

compress int

encryptionAlg string

userSaltHex string

ckSaltHex string

round int

userIvHex string

masterKeyBlobHex string

一些debug信息,方便了解上述具体内容

···

agic: ANDROID BACKUP

Version: 3

Compressed: 1

Algorithm: AES-256

IV: 1539D61DC22C13259102B5F20B7E9C3D

MK: EC78A761EDAE9E578A1CAE125331BF0C1D9178781C1D997711867EE7717EC30B

MK checksum: 944120ED555A34C6559D1793A322B5B59CED1AB8B19275DB7A482984B06ED4A7

key bytes: EC78A761EDAE9E578A1CAE125331BF0C1D9178781C1D997711867EE7717EC30B

salt bytes: D12A67D559DE5B025E7D0C5D41E27A49C9E7E9502F755E23B3E964969E0AA83DD70235E41C5A72BFD2EA0E2112E36E4827AB54F20FDEFC62F353CD557983378B

Calculated MK checksum (use UTF-8: true): 944120ED555A34C6559D1793A322B5B59CED1AB8B19275DB7A482984B06ED4A7

···

按行来说明

magic 有标题的作用

版本 只支持1-4 v2版本以上要用

是否压缩

采用的加密算法

盐1 userSalt

盐2 ckSalt

rounds

userIvHex

masterkeyBlob 这就是用来加密的密钥了

2 的一点说明

在版本号>2的情况下,用UTF-8存储信息

3 的一点说明

如果是压缩过的,那么只能用压缩流进行解

9 的一点说明

这一段由IV+密钥共同组成

数组的第一个元素代表了IV的长度

加密部分

之后的内容,全都是采用加密并压缩过的密钥流来处理,但是这里有一个蛋疼的问题,我读*.ab文件,读了前9行后,把之后的内容解密,遇到了解密的bug,前面的内容正常,后面就GG了。然后,我的办法是,把这部份内容写入一个单独的文件中。再进行解密。

处理成Go的难点

go中是否有加密流

go中是否有压缩流

go中密钥生成(填充,是否是java BC专有库)与java是否一致

最后分析的结果(也许go的流我还不熟)

go中无aes cbc加密流

go中无压缩流(java.util.zip.InflaterInputStream 对应go里的啥?)

手写pkcs#5 padding

密钥生成,go没有jce怎么搞?

解决方案

go无aes cbc加密流的搞法

先说一下go中cipher 的特点,cbc模式下,这货会保留上一次加密的状态,也就是说,

var 加密机

加密.文本1

加密.文本2

//与下面的操作等价

var 加密机

加密.(文本1+文件2)

之前我也有一个误区,就是流加密不等于块加密。我错了,其实流加密,就是每次读一定的字节数罢了,然后再读一定的字节数,与上一次的结果进行相应模式下的操作,如,cbc异或啦。

而块加密,则是直接把要加密的所有内容一次性读入内存中。

那么,我用go,可每次只读16B的内容加密,好省内存呀!还方便最后一次去填充!

func (tool *Filetool) temp2() {

println("cbc方式读")

fi, _ := os.Open(tool.temp1file)

defer fi.Close()

aesBlockEncrypter, _ := aes.NewCipher(tool.realkey)

aesEncrypter := cipher.NewCBCDecrypter(aesBlockEncrypter, tool.realIV)

fo, _ := os.Create(tool.temp2file)

defer fo.Close()

//tmp := make([]byte, 16)

read := make([]byte, 16)

write := make([]byte, 16)

frist:=true

var n int

for {

n, _ = fi.Read(read)

if n == 0 {

fo.Write(PKCS5UnPadding(write))

break

} else if !frist {

fo.Write(write)

} else {

frist=false

}

aesEncrypter.CryptBlocks(write, read)

//copy(tmp, write)

}

}

go中无压缩流

这个真的很蛋疼,只能把解密之后的内容写入一个文件,然后再解密。

func (tool *Filetool) final() {

inputFile, _ := os.Open(tool.temp2file) //变量指向os.Open打开的文件时生成的文件句柄

zf, err := zlib.NewReader(inputFile)

if err != nil {

return

}

defer zf.Close()

//tarFilePath = filepath.Join(t.parseBackupTask.backupPath, fmt.Sprintf("backup_%d.tar", api.GetEvidenceID()))

//os.MkdirAll(filepath.Dir(path), os.ModePerm)

tarFile:=tool.outfileh

if err != nil {

return

}

defer tarFile.Close()

io.Copy(tarFile, zf)

}

完整代码等我有空再传吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值