public static boolean verifyApk(File file) throws IOException { ApkVerifier verifier = new Builder(file).build(); try { Result result = verifier.verify(); return result.isVerified() && result.isVerifiedUsingV1Scheme() && result.isVerifiedUsingV2Scheme(); } catch (ApkFormatException e) { throw new IOException(e); } catch (NoSuchAlgorithmException e) { throw new IOException(e); } }
ApkVerifier verifier = new ApkVerifier.Builder(openFile).build(); try { ApkVerifier.Result result = verifier.verify(); StringEscapeUtils.Builder builder = StringEscapeUtils.builder(StringEscapeUtils.ESCAPE_HTML4); builder.append("<h1>APK signature verification result:</h1>"); if (result.isVerified()) { builder.escape(NLS.str("apkSignature.verificationSuccess")); } else { writeIssues(builder, err, result.getErrors()); writeIssues(builder, warn, result.getWarnings()); if (!result.getV1SchemeSigners().isEmpty()) { builder.append("<h2>"); builder.escape(String.format(result.isVerifiedUsingV1Scheme() ? sigSucc : sigFail, 1)); builder.append("</h2>\n"); for (ApkVerifier.Result.V1SchemeSignerInfo signer : result.getV1SchemeSigners()) { builder.append("<h3>"); builder.escape(NLS.str("apkSignature.signer")); builder.append(" "); builder.escape(signer.getName()); builder.append(" ("); builder.escape(signer.getSignatureFileName()); builder.append(")"); builder.append("</h3>"); writeCertificate(builder, signer.getCertificate()); writeIssues(builder, err, signer.getErrors());
i.getIssue() == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList()); if (!unprotIssues.isEmpty()) { builder.append("<h4>"); builder.append("</h4><blockquote>"); for (ApkVerifier.IssueWithParams issue : unprotIssues) { builder.escape((String) issue.getParams()[0]); builder.append("<br>"); i.getIssue() != ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList()); if (!remainingIssues.isEmpty()) { builder.append("<pre>\n"); for (ApkVerifier.IssueWithParams issue : remainingIssues) { builder.escape(issue.toString()); builder.append("\n");
private void assertThatApksAreSigned( BuildApksResult result, ZipFile apkSetFile, X509Certificate expectedCertificate) throws Exception { for (Variant variant : result.getVariantList()) { for (ApkSet apkSet : variant.getApkSetList()) { for (ApkDescription apkDescription : apkSet.getApkDescriptionList()) { File apk = extractFromApkSetFile(apkSetFile, apkDescription.getPath(), outputDir); ApkVerifier.Result verifierResult = new ApkVerifier.Builder(apk).build().verify(); assertThat(verifierResult.isVerified()).isTrue(); assertThat(verifierResult.getSignerCertificates()).containsExactly(expectedCertificate); } } } }
try { SignerConfig signerConfig = new SignerConfig.Builder( SIGNER_CONFIG_NAME, signingConfig.getPrivateKey(), signingConfig.getCertificates()) .build(); new ApkSigner.Builder(ImmutableList.of(signerConfig)) .setInputApk(unsignedApk.toFile()) .setOutputApk(signedApk.toFile()) .build(); apkSigner.sign();
@Override public OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); checkV1SigningDoneIfEnabled(); if (!mV2SigningEnabled) { return null; } invalidateV2Signature(); byte[] apkSigningBlock = V2SchemeSigner.generateApkSigningBlock( zipEntries, zipCentralDirectory, zipEocd, mV2SignerConfigs); mAddV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock); return mAddV2SignatureRequest; }
@Override public void outputDone() { checkNotClosed(); checkV1SigningDoneIfEnabled(); checkV2SigningDoneIfEnabled(); }
@Override public DataSink getDataSink() { synchronized (mLock) { checkNotDone(); if (mDataSink == null) { mDataSink = new MessageDigestSink(new MessageDigest[] {getMessageDigest()}); } return mDataSink; } }
@Override public InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) { checkNotClosed(); return getInputJarEntryOutputPolicy(entryName); }
@Override public void inputApkSigningBlock(DataSource apkSigningBlock) { checkNotClosed(); if ((apkSigningBlock == null) || (apkSigningBlock.size() == 0)) { return; } if (mOtherSignersSignaturesPreserved) { // TODO: Preserve blocks other than APK Signature Scheme v2 blocks of signers configured // in this engine. return; } // TODO: Preserve blocks other than APK Signature Scheme v2 blocks. }
private void invalidateV1Signature() { if (mV1SigningEnabled) { mV1SignaturePending = true; } invalidateV2Signature(); }
/** * Returns an {@link ApkVerifier} initialized according to the configuration of this * builder. */ public ApkVerifier build() { return new ApkVerifier( mApkFile, mApkDataSource, mMinSdkVersion, mMaxSdkVersion); } }
/** * Returns a new {@code SignerConfig} instance configured based on the configuration of * this builder. */ public SignerConfig build() { return new SignerConfig( mName, mPrivateKey, mCertificates); } }
/** * Returns a new {@code SignerConfig} instance configured based on the configuration of * this builder. */ public SignerConfig build() { return new SignerConfig( mName, mPrivateKey, mCertificates); } }
/** * Returns a new {@code DefaultApkSignerEngine} instance configured based on the * configuration of this builder. */ public DefaultApkSignerEngine build() throws InvalidKeyException { return new DefaultApkSignerEngine( mSignerConfigs, mMinSdkVersion, mV1SigningEnabled, mV2SigningEnabled, mOtherSignersSignaturesPreserved, mCreatedBy); }
/** * Sets whether signatures produced by signers other than the ones configured in this engine * should be copied from the input APK to the output APK. * * <p>By default, signatures of other signers are omitted from the output APK. * * <p><em>Note:</em> This method may only be invoked when this builder is not initialized * with an {@link ApkSignerEngine}. * * @throws IllegalStateException if this builder was initialized with an * {@link ApkSignerEngine} */ public Builder setOtherSignersSignaturesPreserved(boolean preserved) { checkInitializedWithoutEngine(); mOtherSignersSignaturesPreserved = preserved; return this; }
@Override public void done() { synchronized (mLock) { if (mDone) { return; } mDone = true; mDigest = getMessageDigest().digest(); mMessageDigest = null; mDataSink = null; } }
public void addWarning(Issue msg, Object... parameters) { mWarnings.add(new IssueWithParams(msg, parameters)); }
public static boolean apkVerified(File f) throws ApkFormatException, NoSuchAlgorithmException, IOException { ApkVerifier verifier = new Builder(f).build(); Result result = verifier.verify(); return result.isVerified() && result.isVerifiedUsingV1Scheme() && result.isVerifiedUsingV2Scheme() && !result.containsErrors(); } }
public void testOverrideSignature() throws IOException, ApkFormatException, NoSuchAlgorithmException { File f = newTestFile(); // don't write with APK Signature Scheme v2 Block ID 0x7109871a PackerCommon.writeString(f, "OverrideSignatureSchemeBlock", 0x7109871a); assertEquals("OverrideSignatureSchemeBlock", PackerCommon.readString(f, 0x7109871a)); ApkVerifier verifier = new Builder(f).build(); Result result = verifier.verify(); final List<IssueWithParams> errors = result.getErrors(); if (errors != null && errors.size() > 0) { for (IssueWithParams error : errors) { System.out.println("testOverrideSignature " + error); } } assertTrue(result.containsErrors()); assertFalse(result.isVerified()); assertFalse(result.isVerifiedUsingV1Scheme()); assertFalse(result.isVerifiedUsingV2Scheme()); }