sha1-collision & android signature algorithm

SHA1-Collision & Android Sign

参看SHA1-collision我们可以知道,SHA-1签名已经不安全了,签名算法可以考虑升级到SHA-2或者其他算法。

0x01 SHA1-Collision

1. SHA-1是什么?

SHA-1(英语:Secure Hash Algorithm 1,中文名:安全散列算法1)是一种密码散列函数,美国国家安全局设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准(FIPS)[2]。SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数,参考:SHA-1

2. SHA1-Collision是什么?

两个内容不同的数据,SHA-1算法会生成相同的摘要信息,参考:SHA1 collision Two PDF

3. SHA1-Collision对Android的影响

Android SDK默认对apk使用SHA-1签名,在最坏的情况下,攻击者可以伪造SHA-1值相同的文件替换已签名apk中的文件来达到攻击的目的。

0x02 Android的证书验证机制

我们知道Android的Apk文件是一个压缩文件,文件结构大致如下:

.
├── AndroidManifest.xml
├── META-INF
│   ├── CERT.RSA
│   ├── CERT.SF
│   └── MANIFEST.MF
├── assets
├── classes.dex
├── classes2.dex
├── classes3.dex
├── lib
├── res
└── resources.arsc

apk相关的签名相关的文件在META-INF目录中,其中:

  • MANIFEST.MF
    遍历APK包中除了META-INF\文件夹以外的所有文件,利用SHA-1算法生成这些文件的消息摘要,然后转化为对应的base64编码。MANIFEST.MF存储的是文件的摘要值,保证完整性,防止文件被篡改。

  • .SF
    xx.SF文件(xx为使用者证书的自定义别名,默认为CERT,即CERT.SF),保存的是MANIFEST.MF的摘要值, 以及MANIFEST.MF中每一个摘要项的摘要值,然后转化成对应的base64编码。虽然该文件的后缀名.sf(SignatureFile)看起来是签名文件,但是并没有私钥参与运算,也不保存任何签名内容。

  • .RSA/.DSA
    .RSA/.DSA文件(后缀不同采用的签名算法不同,.RSA使用的是RSA算法,.DSA使用的是数字签名算法DSA,目前APK主要使用的是这两种算法),保存的是第二项.SF文件的数字签名,同时还会包括签名采用的数字证书(公钥)。特别说明,当使用多重证书签名时,每一个.sf文件必须有一个.RSA/.DSA文件与之对应,也就是说使用证书CERT1签名时有CERT1.SF和CERT1.RSA,同时采用证书CERT2签名时又会生成CERT2.SF和CERT2.RSA。

Android 系统不允许安装没有任何数字签名的应用APK程序,所有应用程序必须使用某个证书进行签名(一般为应用开发者自签名证书),
APK源文件,首先由应用开发者使用自己的私钥,对整个文件进行签名,生成上述的三个文件,然后打包成签名后的APK文件;然后发布到市场。

用户从市场下载APK安装文件,在真正安装APK前,会首先验证数字签名。具体步骤:

  1. 首先计算除META-INF\ 文件夹以外所有文件的SHA1摘要值,同MANIFEST.MF文件中的摘要值做比对。如果不同,则证明源文件被篡改,验证不通过,拒绝安装。
  2. 计算MANIFEST.MF的摘要值, 以及MANIFEST.MF中每一个摘要项的摘要值,同.SF文件中的摘要值做比对。如果不同,则证明.SF被篡改,验证不通过,拒绝安装。
  3. 从.RSA 文件中取出开发者证书,然后从证书中提取开发者公钥,用该公钥对.SF文件做数字签名,并将结果同.RSA文件中的.SF签名进行比对。如果不同,则验证不通过,拒绝安装。

摘自:Shadows Everywhere

0x03 Android支持的签名算法

android 4.3之前不支持SHA1之外的其他签名算法,在4.3之后支持了SHA2等算法,详见:

There is security vs compatibility trade off a few might be interested in. Pre-4.3, Android did not support any signature algorithms except SHA1. With Android >= 4.3, SHA256 support was fixed, and SHA384, SHA512, and ECDSA were added (source). There are still android 2.3.3 (android-10) devices being sold, so anyone interested in backwards compatibility will have to heed this.

测试例子详见:how-to-migrate-your-android-apps-signing-key

下面是提交给google的bug链接:APKs signed using SHA256withRSA or with individual files hashed using SHA-256 fail to install

在android 4.3版本之前的手机上面安装使用sha-256签名的app时,错误日志信息大致如下:

adb install -r Downloads/notepad-sha256withrsa-sha256.apk
~/Downloads/notepad-sha256withrsa-sha256.apk: 1 file pushed. 4.3 MB/s (62395 bytes in 0.014s)
    pkg: /data/local/tmp/notepad-sha256withrsa-sha256.apk
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

0x04 签名生成与查看

  • 生成keystore
keytool -genkey -v -keystore test.keystore -alias testkey -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -dname "cn=Test,ou=Test,c=CA" -validity 10000
  • 查看APK的签名算法
keytool -printcert -jarfile notepad-sha1withrsa-sha1.apk
  • 查看keystore
keytool -list -v -keystore test.keystore
  • jarsigner签名
jarsigner -keystore mykeystore -storepass password -sigalg SHA256withRSA -digestalg SHA256 my.apk test 

0x05 jarsigner与apksigner的区别

jarsigner是jdk自带的工具,apksigner是android sdk自带的工具(build-tools 24.0.3+版本才拥有)。在android build-tools 24.0.3以前默认使用jarsigner对app进行签名,在24.0.3版本以及之后使用apksigner进行签名,其中apksigner签名算法根据android的最低版本的不同而不同,jarsigner则可以直接指定签名算法(见: 上面的jarsigner签名)。

tool minSdkVersion < 18 minSdkVersion >= 18
apksigner SHA1withRSA SHA256withRSA
apksigner SHA1withDSA SHA256withDSA
apksigner SHA256withEC

代码详见com.android.apksig.internal.apk.v1.V1SchemeSigner:

public static DigestAlgorithm getSuggestedSignatureDigestAlgorithm(PublicKey signingKey, int minSdkVersion)
  throws InvalidKeyException
{
  String keyAlgorithm = signingKey.getAlgorithm();
  if ("RSA".equalsIgnoreCase(keyAlgorithm))
  {
    if (minSdkVersion < 18) {
      return DigestAlgorithm.SHA1;
    }
    return DigestAlgorithm.SHA256;
  }
  if ("DSA".equalsIgnoreCase(keyAlgorithm))
  {
    if (minSdkVersion < 21) {
      return DigestAlgorithm.SHA1;
    }
    return DigestAlgorithm.SHA256;
  }
  if ("EC".equalsIgnoreCase(keyAlgorithm))
  {
    if (minSdkVersion < 18) {
      throw new InvalidKeyException("ECDSA signatures only supported for minSdkVersion 18 and higher");
    }
    return DigestAlgorithm.SHA256;
  }
  throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
}  

关于ApkSigner更多信息,请戳~

0x06 升级签名算法为SHA-2

综上所示,我们可以知道App使用签名算法的地方有两处,分别是:

  1. 使用keytools生成keystore时指定的算法。
  2. 使用jarsigner/apksigner和keystore对app进行签名时指定的算法。

这里我们不修改签名文件keystore的签名算法,我们只修改签名App时使用的签名算法为SHA-2,鉴于上面的原因我们需要升级android app的minSdkVersion >= 18,下面介绍两种升级SHA-2的方法:

  • 升级buildToolsVersion的版本大于等于24.0.3,gradle打包时会自动调用apksigner使用SHA256withRSA对app进行签名。
  • 使用jarsigner对app进行签名,然后在命令参数中直接指定签名算法即可。

0x07 遗留问题

由于keystore未发生变化,所以使用不同签名算法的app是可以互相覆盖的,故而攻击者也可以使用旧版本的apk(使用SHA-1)覆盖新版本apk(使用SHA-2)继续进行攻击,所以为了避免被攻击者进行攻击的最好更换keystore,但是这样就没法覆盖安装了,详细请参考things-that-cannot-change

0x08 参考引用

  1. Announcing the first SHA1 collision
  2. SHA1 collision Two PDF
  3. things-that-cannot-change
  4. SHA-1
  5. Shadows Everywhere
  6. apksigner
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容