日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

新一代开源Android渠道包生成工具Walle

發(fā)布時間:2025/3/15 Android 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 新一代开源Android渠道包生成工具Walle 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)載自[http://tech.meituan.com/android-apk-v2-signature-scheme.html]

在Android 7.0(Nougat)推出了新的應(yīng)用簽名方案APK Signature Scheme v2后,之前快速生成渠道包的方式(美團Android自動化之旅—生成渠道包)已經(jīng)行不通了,在此應(yīng)用簽名方案下如何快速生成渠道包呢?

本文會對新的應(yīng)用簽名方案APK Signature Scheme v2以及新一代渠道生成工具進行詳細深入的介紹。

新的應(yīng)用簽名方案APK Signature Scheme v2

Android 7.0(Nougat)引入一項新的應(yīng)用簽名方案APK Signature Scheme v2,它是一個對全文件進行簽名的方案,能提供更快的應(yīng)用安裝時間、對未授權(quán)APK文件的更改提供更多保護,在默認情況下,Android Gradle 2.2.0插件會使用APK Signature Scheme v2和傳統(tǒng)簽名方案來簽署你的應(yīng)用。

下面以?新的應(yīng)用簽名方案?來指APK Signature Scheme v2。

目前該方案不是強制性的,在?build.gradle?添加?v2SigningEnabled false?,就能使用傳統(tǒng)簽名方案來簽署我們的應(yīng)用(見下面的代碼片段)。

android {...defaultConfig { ... }signingConfigs {release {storeFile file("myreleasekey.keystore")storePassword "password"keyAlias "MyReleaseKey"keyPassword "password"v2SigningEnabled false}}}

但新的應(yīng)用簽名方案有著良好的向后兼容性,能完全兼容低于Android 7.0(Nougat)的版本。對比舊簽名方案,它有更快的驗證速度和更安全的保護,因此新的應(yīng)用簽名方案可能會被采納成一個強制配置,筆者認為現(xiàn)在有必要對現(xiàn)有的渠道包生成方式進行檢查、升級或改造來支持新的應(yīng)用簽名方案。

新的簽名方案對已有的渠道生成方案有什么影響呢?下圖是新的應(yīng)用簽名方案和舊的簽名方案的一個對比:

新的簽名方案會在ZIP文件格式的?Central Directory?區(qū)塊所在文件位置的前面添加一個APK Signing Block區(qū)塊,下面按照ZIP文件的格式來分析新應(yīng)用簽名方案簽名后的APK包。

整個APK(ZIP文件格式)會被分為以下四個區(qū)塊:

  • Contents of ZIP entries(from offset 0 until the start of APK Signing Block)
  • APK Signing Block
  • ZIP Central Directory
  • ZIP End of Central Directory


  • 新應(yīng)用簽名方案的簽名信息會被保存在區(qū)塊2(APK Signing Block)中, 而區(qū)塊1(Contents of ZIP entries)、區(qū)塊3(ZIP Central Directory)、區(qū)塊4(ZIP End of Central Directory)是受保護的,在簽名后任何對區(qū)塊1、3、4的修改都逃不過新的應(yīng)用簽名方案的檢查。

    之前的渠道包生成方案是通過在META-INF目錄下添加空文件,用空文件的名稱來作為渠道的唯一標識,之前在META-INF下添加文件是不需要重新簽名應(yīng)用的,這樣會節(jié)省不少打包的時間,從而提高打渠道包的速度。但在新的應(yīng)用簽名方案下META-INF已經(jīng)被列入了保護區(qū)了,向META-INF添加空文件的方案會對區(qū)塊1、3、4都會有影響,新應(yīng)用簽名方案簽署的應(yīng)用經(jīng)過我們舊的生成渠道包方案處理后,在安裝時會報以下錯誤:

    Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from base.apk: META-INF/CERT.SF indicates base.apk is signed using APK Signature Scheme v2, but no such signature was found. Signature stripped?]

    目前另外一種比較流行的渠道包快速生成方案(往APK中添加ZIP Comment)也因為上述原因,無法在新的應(yīng)用簽名方案下進行正常工作。

    如果新的應(yīng)用簽名方案后續(xù)改成強制要求,那我們現(xiàn)有的生成渠道包的方式就會無法工作,那我們難道要退回到解放前,通過傳統(tǒng)的方式(例如:使用APKTool逆向工具、采用Flavor + BuildType等比較耗時的方案來進行渠道包打包)來生成支持新應(yīng)用簽名方案的渠道包嗎?

    如果只有少量渠道包的場景下,這種耗時時長還能夠勉強接受。但是目前我們有將近900個渠道,如果采用傳統(tǒng)方式打完所有的渠道包需要近3個小時,這是不能接受的。

    那我們有沒有其他更好的渠道包生成方式,既能支持新的應(yīng)用簽名方案,又能體驗毫秒級的打包耗時呢?我們來分析一下新方案中的區(qū)塊2——Block。

    可擴展的APK Signature Scheme v2 Block

    通過上面的描述,可以看出因為APK包的區(qū)塊1、3、4都是受保護的,任何修改在簽名后對它們的修改,都會在安裝過程中被簽名校驗檢測失敗,而區(qū)塊2(APK Signing Block)是不受簽名校驗規(guī)則保護的,那是否可以在這個不受簽名保護的區(qū)塊2(APK Signing Block)上做文章呢?我們先來看看對區(qū)塊2格式的描述:

    偏移字節(jié)數(shù)描述
    @+0 8這個Block的長度(本字段的長度不計算在內(nèi))
    @+8 n一組ID-value
    @-24 8這個Block的長度(和第一個字段一樣值)
    @-16 16魔數(shù) “APK Sig Block 42”

    區(qū)塊2中APK Signing Block是由這幾部分組成:2個用來標示這個區(qū)塊長度的8字節(jié) + 這個區(qū)塊的魔數(shù)(APK Sig Block 42)+ 這個區(qū)塊所承載的數(shù)據(jù)(ID-value)。

    我們重點來看一下這個ID-value,它由一個8字節(jié)的長度標示+4字節(jié)的ID+它的負載組成。V2的簽名信息是以ID(0x7109871a)的ID-value來保存在這個區(qū)塊中,不知大家有沒有注意這是一組ID-value,也就是說它是可以有若干個這樣的ID-value來組成,那我們是不是可以在這里做一些文章呢?

    為了驗證我們的想法,先來看看新的應(yīng)用簽名方案是怎么驗證簽名信息的,見下圖:





    通過上圖可以看出新的應(yīng)用簽名方案的驗證過程:

  • 尋找APK Signing Block,如果能夠找到,則進行驗證,驗證成功則繼續(xù)進行安裝,如果失敗了則終止安裝
  • 如果未找到APK Signing Block,則執(zhí)行原來的簽名驗證機制,也是驗證成功則繼續(xù)進行安裝,如果失敗了則終止安裝
  • 那Android應(yīng)用在安裝時新的應(yīng)用簽名方案是怎么進行校驗的呢?筆者通過翻閱Android相關(guān)部分的源碼,發(fā)現(xiàn)下面代碼段是用來處理上面所說的ID-value的:

    public static ByteBuffer findApkSignatureSchemeV2Block(ByteBuffer apkSigningBlock,Result result) throws SignatureNotFoundException {checkByteOrderLittleEndian(apkSigningBlock);// FORMAT:// OFFSET DATA TYPE DESCRIPTION// * @+0 bytes uint64: size in bytes (excluding this field)// * @+8 bytes pairs// * @-24 bytes uint64: size in bytes (same as the one above)// * @-16 bytes uint128: magicByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24);int entryCount = 0;while (pairs.hasRemaining()) {entryCount++;if (pairs.remaining() < 8) {throw new SignatureNotFoundException("Insufficient data to read size of APK Signing Block entry #" + entryCount);}long lenLong = pairs.getLong();if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) {throw new SignatureNotFoundException("APK Signing Block entry #" + entryCount+ " size out of range: " + lenLong);}int len = (int) lenLong;int nextEntryPos = pairs.position() + len;if (len > pairs.remaining()) {throw new SignatureNotFoundException("APK Signing Block entry #" + entryCount + " size out of range: " + len+ ", available: " + pairs.remaining());}int id = pairs.getInt();if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {return getByteBuffer(pairs, len - 4);}result.addWarning(Issue.APK_SIG_BLOCK_UNKNOWN_ENTRY_ID, id);pairs.position(nextEntryPos);}throw new SignatureNotFoundException("No APK Signature Scheme v2 block in APK Signing Block");}

    上述代碼中關(guān)鍵的一個位置是?if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {return getByteBuffer(pairs, len - 4);},通過源代碼可以看出Android是通過查找ID為?APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a?的ID-value,來獲取APK Signature Scheme v2 Block,對這個區(qū)塊中其他的ID-value選擇了忽略。

    在APK Signature Scheme v2中沒有看到對無法識別的ID,有相關(guān)處理的介紹。

    當看到這里時,我們可不可以設(shè)想一下,提供一個自定義的ID-value并寫入該區(qū)域,從而為快速生成渠道包服務(wù)呢?

    怎么向ID-value中添加信息呢?通過閱讀ZIP的文件格式和APK Signing Block格式的描述,筆者通過編寫下面的代碼片段進行驗證,發(fā)現(xiàn)通過在已經(jīng)被新的應(yīng)用簽名方案簽名后的APK中添加自定義的ID-value,是不需要再次經(jīng)過簽名就能安裝的,下面是部分代碼片段。

    public void writeApkSigningBlock(DataOutput dataOutput) {long length = 24;for (int index = 0; index < payloads.size(); ++index) {ApkSigningPayload payload = payloads.get(index);byte[] bytes = payload.getByteBuffer();length += 12 + bytes.length;}ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES);byteBuffer.order(ByteOrder.LITTLE_ENDIAN);byteBuffer.putLong(length);dataOutput.write(byteBuffer.array());for (int index = 0; index < payloads.size(); ++index) {ApkSigningPayload payload = payloads.get(index);byte[] bytes = payload.getByteBuffer();byteBuffer = ByteBuffer.allocate(Integer.BYTES);byteBuffer.order(ByteOrder.LITTLE_ENDIAN);byteBuffer.putInt(payload.getId());dataOutput.write(byteBuffer.array());dataOutput.write(bytes);}...}

    新一代渠道包生成工具

    到這里為止一個新的渠道包生成方案逐步清晰了起來,下面是新一代渠道包生成工具的描述:

  • 對新的應(yīng)用簽名方案生成的APK包中的ID-value進行擴展,提供自定義ID-value(渠道信息),并保存在APK中
  • 而APK在安裝過程中進行的簽名校驗,是忽略我們添加的這個ID-value的,這樣就能正常安裝了
  • 在App運行階段,可以通過ZIP的EOCD(End of central directory)、Central directory等結(jié)構(gòu)中的信息(會涉及ZIP格式的相關(guān)知識,這里不做展開描述)找到我們自己添加的ID-value,從而實現(xiàn)獲取渠道信息的功能
  • 新一代渠道包生成工具完全是基于ZIP文件格式和APK Signing Block存儲格式而構(gòu)建,基于文件的二進制流進行處理,有著良好的處理速度和兼容性,能夠滿足不同的語言編寫的要求,目前筆者采用的是Java+Groovy開發(fā), 該工具主要有四部分組成:

  • 用于寫入ID-value信息的Java類庫
  • Gradle構(gòu)建插件用來和Android的打包流程進行結(jié)合
  • 用于讀取ID-value信息的Java類庫
  • 用于供com.android.application使用的讀取渠道信息的AAR
  • 這樣,每打一個渠道包只需復制一個APK,然后在APK中添加一個ID-value即可,這種打包方式速度非常快,對一個30M大小的APK包只需要100多毫秒(包含文件復制時間)就能生成一個渠道包,而在運行時獲取渠道信息只需要大約幾毫秒的時間。

    這個項目我們?nèi)∶麨閃alle(瓦力),已經(jīng)開源,項目的Github地址是:?https://github.com/Meituan-Dianping/walle?(求Issue、PR、Star)。希望業(yè)內(nèi)有類似需求的團隊能夠在APK Signature Scheme V2簽名下愉快地生成渠道包,同時也期待大家一起對該項目進行完善和優(yōu)化。

    總結(jié)

    以上就是我們對新的應(yīng)用簽名方案進行的分析,并根據(jù)它所帶來的文件存儲格式上的變化,找到了可以利用的ID-value,然后基于這個ID-value來構(gòu)建我們新一代渠道包生成工具。

    新一代渠道包生成工具能夠滿足新應(yīng)用簽名方案對安全性的要求,同時也能滿足對渠道包打包時間的要求,至此大家生成渠道包的方式需要升級了!

    文章中引用的圖片來源于:https://source.android.com/security/apksigning/v2.html

    參考文獻

  • APK Signature Scheme v2
  • ApkSigner的源代碼
  • apksig的源代碼
  • ZIP Format
  • 總結(jié)

    以上是生活随笔為你收集整理的新一代开源Android渠道包生成工具Walle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日产av在线 | 国产精品欧美亚洲 | 天天综合中文字幕 | 熟睡人妻被讨厌的公侵犯 | 久久久久99精品成人片三人毛片 | 欧美成人一区二区三区高清 | 欧美裸体xxxx极品少妇 | 熟妇人妻无乱码中文字幕真矢织江 | www.youji.com| 日韩国产精品一区 | 毛片无遮挡 | 久久老司机 | 亚洲专区第一页 | 嫩草av久久伊人妇女超级a | av免费网址在线观看 | 水蜜桃av在线 | 天天看av | 日韩不卡毛片 | 99在线播放视频 | 天堂精品视频 | 中文字幕在线免费观看 | 97精品人妻一区二区 | 黄色一大片 | 中文字幕不卡在线观看 | 久久精品精品 | 国产xxxxwwww | 亚洲人丰满奶水 | 日本一区二区在线不卡 | 黄色1级毛片 | 亚洲激情在线 | 成人激情片 | av色欲无码人妻中文字幕 | 欧美激情第1页 | 九色在线视频 | 神马一区二区三区 | 男人天堂av网 | 亲切的金子片段 | 8090理论片午夜理伦片 | 裸体美女免费视频网站 | 日本a v网站 | 男女视频国产 | 越南黄色一级片 | 亚洲中文字幕第一区 | 人人插人人澡 | 日韩av一 | 中文字幕在线不卡 | 天天5g天天爽免费观看 | 东北少妇av| 色就是色av | 深爱开心激情网 | av在线免费播放网站 | 欧洲亚洲自拍 | 国产极品在线观看 | 极品尤物一区二区 | 久久亚洲国产成人精品性色 | 天天爱天天做天天爽 | 国产乱码一区二区三区播放 | mm1313亚洲精品| aaaa黄色片 | 精品国产一区二区三区四区精华 | 久久av一区| 热久久影院 | 国产大学生视频 | 一女三黑人理论片在线 | 竹菊影视一区二区三区 | 丝袜黄色片 | 草草久久久无码国产专区 | 国产视频一区二 | 精品伊人久久 | 国产粉嫩在线观看 | 一级在线看 | 欧美在线亚洲 | 91精品国产乱码久久久张津瑜 | 日本美女性生活视频 | 乱淫的女高中暑假调教h | 亚洲第一福利网站 | 手机av在线免费观看 | av一本二本 | 双性懵懂美人被强制调教 | 国产日韩欧美综合在线 | 91精品福利在线 | 国产精品一区二区免费看 | 日韩一区二区三区高清 | 日韩精品成人在线观看 | 日韩三区四区 | 日韩高清不卡在线 | 白嫩情侣偷拍呻吟刺激 | 狠狠干男人的天堂 | 久久高清 | 精品九九久久 | 在线观看特色大片免费网站 | 欧美高清二区 | 超碰在线观看免费 | 国产av 一区二区三区 | 久草视频在线免费看 | 亚洲bb| 禁断介护av一区二区 | 黄色一级视频免费观看 | 亚洲涩涩在线 |