English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
老签名多渠道打包原理
前言
由于Android7.0发布了新的签名机制,加强了签名的加固,导致在新的签名机制下无法通过美团式的方式再继续打多渠道包了。不过在说新的签名机制对打包方案的
영향과 왜 우리의 원래 패키지 메커니즘에 영향을 미치는지 이해하기 전에, 먼저 패키지 원리와 서명이 전체 패키지 과정에서 어떤 역할을 하는지 간단히 이해해야 합니다.
Android 패키지流程
Android 패키지 과정은 약간 그림에 나와 있듯이, 전체 과정은 Java 코드, 자원 파일 및 제3자 라이브러리를 통합하여 APK 파일로 만들고, 통합된 파일에 대해 서명 및 최적화 정렬을 수행하는 것입니다. 전체 과정은 간단히
단계별로 다음과 같습니다:
APK 생성 단계는 대략 이렇게 됩니다, 우리는 세세한 구현에 대해 신경 쓰지 않아도 됩니다, 이 과정을 약간 이해하면 나중에 우리의 패키지 계획의 원리를 이해할 수 있습니다. 물론, 이렇게 보면 APK
매우 신비로운 파일입니다, 설치하고 실행할 수 있습니다. 실제로, APK는 특별한 .zip 파일일 뿐입니다, 하지만 우리의 Android 기기가 인식하고 앱으로 설치할 수 있습니다. APK 파일을 압축 풀어 내용을 보고 보겠습니다.
파일 내용이 우리가 이전에 말한 것과 기본적으로 일치합니다, 다음에 가장 중요한 폴더를 보고 보겠습니다, 제3장 그림에 있는 파일입니다, 이 파일들은 모두 META에 있습니다.-INF 파일 폴더에, 이것이 우리가 서명 과정에서 APK의 유일한 식별자로 추가한 파일입니다. 이렇게 되면 우리의 패키지 최적화에 대해 무엇이 의미가 있을까요, 여기서는 먼저 의문을 보관하고, 나중에 이야기하겠습니다. 이를 이해하기 전에 먼저 서명 이야기를 정리해야 합니다.
서명의 역할과 원리
서명의 역할
Android App은 개발 중에 유일한 식별자가 있으며, 우리는 이를 패키지 이름이라고 부릅니다. 예를 들어, 대 클라이언트의 패키지 이름은 com.Quanr입니다. 패키지 이름은 신분증 번호와 마찬가지로, 각 사람과 일일이 일치합니다. App을 설치할 때, 기기는 패키지 이름을 통해 애플리케이션을 인식합니다. 기기에서는 두 개의 패키지 이름이 같은 애플리케이션이 존재할 수 없습니다. 이것이 App의 기기 내 유일성입니다. 우리가 App을 업그레이드할 때, 예를 들어, 덮어 설치할 때, 패키지 이름을 통해 인식하고 대응하여 App이 원활하게 업그레이드되고 다른 App이 덮어 설치되지 않도록 보장할 수 있습니다. 마찬가지로, 다른 App의 패키지 이름이 다를 경우 우리의 App을 덮어 설치할 수 없습니다. Android는 패키지 이름 인식 메커니즘을 제공하지만, 패키지 이름만으로는 충분하지 않습니다. 다른 사람이 우리의 패키지 이름을 사용하여 새로운 App을 만들어 우리의 App을 덮어 설치하려고 하거나, 범죄자가 우리의 패키지 이름을 해독하려고 할 수 있습니다.
App은 자신의 내용을 추가할 수 있습니다. 예를 들어, 내장 광고를 통해 이익을 추구하고, 수정된 App을 다시 배포하여 사용자가 덮어 설치하도록 하면, 우리는 큰 손실을 입을 수 있습니다. 물론 이러한 일은 일어나지 않을 것입니다. Google은 각 App에 서명 메커니즘을 추가했습니다. 우리가 은행에서 업무를 처리할 때와 마찬가지로, 신분증을 제공하고 서명을 해야 하며, 신분증 번호는 모두가 볼 수 있지만, 서명은 본인만 할 수 있습니다. 누구도 복사할 수 없습니다. App은 이러한 메커니즘을 통해 유일성과 보안을 보장합니다.
그렇다면, 서명은 어떻게 이러한 일을 할 수 있을까요.
서명의 원리
APK 서명에는 여러 가지 도구가 있지만, 원리는 모두 비슷합니다. 여기서 signapk 도구를 예로 들어보겠습니다. APK에 서명하려면 이 도구와 몇 가지 파라미터, 우리의 유일한 서명 파일만으로도 충분합니다. 도구를 사용하여 서명하는 것은 매우 간단합니다. 우리가 더 중요하게 고려해야 할 것은 그 원리와 구체적인 구현 방법입니다. 이렇게 하면 우리가 채널 패키지의 비밀을 찾아낼 수 있습니다. 서명 도구를 사용하기 전에, 서명에 필요한 비밀키와 공개키(a–(비밀키)–>b–(공개키)–>a)를 준비해야 하며, 그런 다음 APK에 서명을 부여합니다. 서명 프로세스는 APK에서 새로운 META 파일을 생성합니다.-INF 폴더를 열고 그 안에 세 파일을 생성하면, 이 세 파일은 서명의 핵심이며 검증의 근거가 됩니다.
그림에서 볼 수 있듯이 세 파일은 다음과 같습니다:
이제 이 세 파일이 어떻게 생성되는지 설명해 보겠습니다.
MANIFEST.MF
콘텐츠를 먼저 보면, Name에 대한 SHA가 나타나게 됩니다.1의 값은 쉽게 알 수 있으며, 이 파일이 각 파일에 대해 유일한 값을 저장하고 있다는 것입니다. MANIIFEST.MF 파일의 기능은 얼마 전에 말한 것처럼, APK에 서명할 때, 먼저 각 파일에 대해 디지털 코드를 부여하여 유일한 SHA를 생성합니다.1의 값도 다르며, 파일 내용이 다르면 해당 SHA1의 값도 다르며, 따라서 파일 내용이 조작되면 해당 SHA1의 값도 변경됩니다. APK를 서명할 때는 자신의 모든 파일을 확인하고, 해당 SHA1그런 다음, 이 내용을 새로운 MANIFEST.MF 파일에 저장하고, 이 파일을 META-INF 디렉토리에서 첫 번째 서명 파일이 생성되었습니다.
CERT.SF
MANIFEST.MF 파일이 생성된 후, 우리는 각 파일의 독특한 값을 기록할 수 있어 파일이 조작되지 않도록 보장할 수 있습니다. 따라서 MANIFEST에 기록된 파일의 보안이 보장되었지만, 자신의 보안을 보장할 수 없으며, 다른 사람도 원래 파일을 수정한 후에 해당 SHA1그런 다음 MANIFEST 파일을 수정하므로, 우리는 MANIFEST를 강화하여 보안성을 보장해야 합니다. 첫 번째 파일 생성 후, 서명 도구는 두 번째 파일을 생성시작합니다. 이 파일은 CERT.RSA입니다. 이 단계에서, 이전 단계에서 생성된 파일에 대해 한 번 더 숫자 코드를 계산하고, 결과를 새로 생성된 CERT.RSA 파일의 헤더에 저장합니다. 그런 다음 MANIFEST.MF 파일의 각 속성 블록에 대해 한 번 더 숫자 코드를 계산하고, 이를 CERT.SF 파일의 하나의 속성 블록에 저장합니다.
CERT.RSA
이 파일들은 모두 이진 파일입니다. CERT.SF 파일을 생성한 후, 우리는 개인 키를 사용하여 CERT.SF를 암호화하여 서명을 계산하고, 얻은 서명과 공개 키의 디지털 인증서 정보를 함께 저장하여 CERT.RSA에, 전체 서명 과정이 끝난다.
아래에서 Apk 설치 과정에서의 검증 단계를 간단히 설명하자. 이는 서명 파일 생성 단계와 유사하다:
위 과정에서 명확하게 문제를 발견할 수 있다. 이 과정에서 META-INF에 있는 모든 파일은 숫자 코드와 암호화가 이루어진다. 이 폴더는 서명을 생성할 때 생성된다. 첫 번째 파일 MANIFEST.MF를 생성할 때 이 폴더에 있는 모든 파일에 대해 숫자 코드가 없었다. 이 폴더는 반드시 비어 있기 때문이다. 두 번째 파일은 첫 번째 파일을 기반으로 생성되고, 세 번째 파일은 두 번째 파일을 기반으로 생성된다. 따라서 전체 과정에서 이 META-INF 폴더는 거의 제어 범위 밖에 있습니다. 그 안에 파일을 추가하여 서명 과정을 피할 수 있습니다. 이것이 메이푸 다중 채널 패키지 계획의 돌파구입니다.
메이푸는 서명 원리를 활용하여 다중 채널 패키징을 완료합니다.
앞서 패키징 과정을 이해한 후, 다른 채널 패키지를 빠르게 패키징하려면 패키징 단계를 건너뛰고 Apk 파일을 직접 수정하는 방법을 생각해야 합니다. 그러나 이는 Android의 서명 검증 규칙을 도전해야 합니다. 그러나, 서명 과정에 대한 분석을 통해, META-INF 폴더에 무작위로 파일을 추가하여 서명 규칙 검사를 피할 수 있습니다. 이 때 새로운 계획은 탄생했습니다. 패키징을 통해 채널이 없는 Apk 파일을 생성한 후, 이를 복사하고 META-INF에 파일을 추가하고, 파일 이름을 통해 채널 번호를 결정합니다. 다른 Apk에서는 META-INF에 다른 채널 이름 파일을 추가하여 다른 채널을 설정할 수 있습니다. 그런 다음, 필요한 시점에 이 파일에서 직접 데이터를 가져올 수 있어서, 패키징 과정을 완벽히 건너뛰 수 있습니다. 이 방식의 소요 시간은 무엇인가요? 이动作는 단지 Apk 파일을 기반으로 파일을 복사하고 삽입하는 것뿐입니다. 이 작업은 고성능 컴퓨터에서는 한 분 만에 할 수 있습니다.900 번. 따라서, 이때 채널 패키지를 패키징하는 데 필요한 시간은4분,100 개의 채널 패키지도 네 분과 약간의 추가 시간만 필요합니다. 물론, 이것이 최적의 시간은 아닙니다. 만약900 개의 채널을 가진 경우, 각 채널 패키지를 패키징하는 데 필요한 시간은900x4분, 메이푸 계획은 단지5분, 수백 배의 효율성을 높였습니다. 따라서 메이푸 계획은 오래된 서명에서 매우 완벽하다고 할 수 있습니다.
새로운 서명 방식이 기존 계획에 미치는 영향
Android에서 7.0 이후로, Google은 서명의 보안성을 강화하기 위해 새로운 서명 검증 규칙을 도입했습니다. 각 파일에 대해 디지털 코드를 부여하는 것은 아니며, 그림에서 보면:
새로운 서명 방식은 zip 파일 구조에 따라 서명을 합니다. Apk 파일은 본질적으로 .zip 파일이며, 그림에서 보면 서명 전에 세 부분으로 나눌 수 있습니다.
아래 그림에서 파란 부분은 ZIP 엔트리의 내용을, 핑크 부분은 Central Directory를 나타냅니다.
File Entry은 파일 엔티티를 나타내며, 압축 파일에는 여러 파일 엔티티가 포함됩니다.
파일 엔티티는 하나의 헤더와 파일 데이터로 구성되어 있으며(압축된 파일, 압축 알고리즘은 헤더에 기록됩니다)
Central Directory는 여러 File header로 구성되어 있으며, 각 File header는 파일 엔티티의 이동한 위치를 저장합니다.
파일은 'End of central directory'라는 구조로 끝납니다.
End of Central Directory의 역할을 다시 볼 수 있습니다. 이는 Central Directory가 헤더에 비해 이동한 위치를 기록하며, 우리의 새로운 서명 데이터 Apk Signing Block은 Contents of ZIP entries와 Central Directory 사이에 위치하고 있습니다. 이는 서명되지 않은 ZIP 파일의 세 개의 모듈의 모든 내용을 인코딩하여 서명한 후 생성된 독특한 데이터입니다. 이는 이전에 말했던 숫자 인코딩에 따라 이해할 수 있습니다. 이 세 부분의 어떤 내용이든 변화가 생기면 이 부분의 데이터도 다릅니다. 따라서 서명 후 APK의 어떤 내용도 수정할 수 없습니다. 하지만 우리는 앞에서도 APK 서명 외의 내용을 수정하지 않았기 때문에, 이 순간 Apk Signing Block의 내용을 수정하는 것을 고려할 수 있을까요? 우리는 이후에 작은 꼬리를 추가합니다. 명백히 이 방법도 망가졌습니다. 앞에서 말했듯이 마지막 부분은 End of Central Direcotry라는 부분으로, Central Direcotry가 ZIP 파일 시작 위치에 비해 이동한 위치를 기록하며, APK Signing Block은 Central Direcotry 앞에 위치하고 있습니다. 만약 APK Signing Block의 길이를 변경하면 Central Direcotry가 헤더에 비해 이동한 위치가 변경되고, 내용이 End of Central Directory에 기록된 것과 다를 것입니다. 따라서 전체 APK 패키지가 손상됩니다. 이 위치를 변경할 수 있을까요? 명백히 이렇지 않습니다. 이 위치를 변경하면 APK Signing Block도 변경되며, 서명 파일을 가진 개발자만이 정확한 APK Signing Block 데이터를 받을 수 있습니다. 이를 조작하려는 사람은 절망할 것입니다. 이것이 새로운 서명 기제의 작동 원리입니다. 이 새로운 기제 하에서, 우리의 이전 서명은 적절히 수정되어야 할 것입니다.
개선 계획의 아이디어
앞에서 말했듯이, 우리의 새로운 패키지 계획은 새로운 서명 기제하에서 다시 한 번 벽에 도달할 것입니다(물론, 고객이 이전 서명을 사용하면 이 문제를 고려할 필요가 없습니다), 하지만, Google이 장량자 계획을 가지고 있으며, 우리는 벽을 넘는 계단을 가지고 있습니다~
이전에 말했듯이 채널 패키지를 추가하는 방법이 여러 가지 있습니다:
이전에 분석했듯이, zip 파일의 모든 모듈 내용을 수정하면 APK Signing Block이 변경되어 서명 메커니즘을 피할 수 없습니다.
그러나 이는 크게 중요하지 않습니다. 서명 메커니즘은 우리의 APK의 안전성을 보장하기 위한 것이며, 우리는 악의적으로 앱을 변조할 의도가 없습니다. 우리는 개발자이며, 서명 파일의 개인 키와 공개 키를 가지고 있습니다. 서명 메커니즘을 피할 수 없다면, 그냥 APK 패키지를 수정하고 다시 서명하면 됩니다. 이러한 방법의 효율성은 서명 메커니즘을 피하는 방법보다 낮지만, 몇 분이 걸리는 패키징 과정보다 이 시간은 수용할 수 있습니다. 일반적으로 다시 서명하는 데는 3-4초가 소요되며, 4분이 걸리는 패키징 과정에 비해 여전히 수용할 수 있고 사용할 수 있습니다.
물론, 이는 우리가 서명 메커니즘을 기반으로 생각한 한 가지 계획입니다. 이전에 패키징과 서명의 전체 프로세스와 메커니즘을 분석했으며, 더 나은 방법이 있을 수도 있습니다. 이는 우리 모두가 창의적이게 생각해야 할 문제입니다. 이러한 프로세스와 원리를 자세히 분석하고 생각하면, 더 나은 솔루션을 찾아서 패키징 계획을 최적화할 수 있을 것입니다.
결론
이것이 Android에 대한 모든 것입니다.7.0 새로운 서명이 다중 채널 패키징에 미치는 모든 내용을 포함합니다.17238; 이 문서의 내용이 Android 개발자들에게 도움이 되기를 바랍니다. 질문이 있으면 댓글을 남겨 주세요.
성명: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자는 모두 소유합니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공 편집 처리를 하지 않으며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반 내용이 있으면 이메일을 notice#w로 보내 주시기 바랍니다.3codebox.com에 이메일을 보내면 (#을 @으로 변경하십시오) 신고하시고 관련 증거를 제공하시면, 확인되면 사이트는 즉시 위반 내용을 삭제합니다.