diff --git a/tools/apksigner/Android.mk b/tools/apksigner/Android.mk
new file mode 100644
index 0000000..a7b4414
--- /dev/null
+++ b/tools/apksigner/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/apksigner/core/Android.mk b/tools/apksigner/core/Android.mk
new file mode 100644
index 0000000..c86208b
--- /dev/null
+++ b/tools/apksigner/core/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+# apksigner library, for signing APKs and verification signatures of APKs
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := apksigner-core
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_LIBRARIES = \
+  bouncycastle-host \
+  bouncycastle-bcpkix-host
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java
new file mode 100644
index 0000000..71e698b
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.apk.v1;
+
+/**
+ * Digest algorithm used with JAR signing (aka v1 signing scheme).
+ */
+public enum DigestAlgorithm {
+    /** SHA-1 */
+    SHA1("SHA-1"),
+
+    /** SHA2-256 */
+    SHA256("SHA-256");
+
+    private final String mJcaMessageDigestAlgorithm;
+
+    private DigestAlgorithm(String jcaMessageDigestAlgoritm) {
+        mJcaMessageDigestAlgorithm = jcaMessageDigestAlgoritm;
+    }
+
+    /**
+     * Returns the {@link java.security.MessageDigest} algorithm represented by this digest
+     * algorithm.
+     */
+    String getJcaMessageDigestAlgorithm() {
+        return mJcaMessageDigestAlgorithm;
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java
new file mode 100644
index 0000000..b99cdec
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.apk.v1;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.DEROutputStream;
+import org.bouncycastle.cert.jcajce.JcaCertStore;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSProcessableByteArray;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.cms.CMSSignedDataGenerator;
+import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+
+import com.android.apksigner.core.internal.jar.ManifestWriter;
+import com.android.apksigner.core.internal.jar.SignatureFileWriter;
+import com.android.apksigner.core.internal.util.Pair;
+
+/**
+ * APK signer which uses JAR signing (aka v1 signing scheme).
+ *
+ * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File">Signed JAR File</a>
+ */
+public abstract class V1SchemeSigner {
+
+    public static final String MANIFEST_ENTRY_NAME = "META-INF/MANIFEST.MF";
+
+    private static final Attributes.Name ATTRIBUTE_NAME_CREATED_BY =
+            new Attributes.Name("Created-By");
+    private static final String ATTRIBUTE_DEFALT_VALUE_CREATED_BY = "1.0 (Android apksigner)";
+    private static final String ATTRIBUTE_VALUE_MANIFEST_VERSION = "1.0";
+    private static final String ATTRIBUTE_VALUE_SIGNATURE_VERSION = "1.0";
+
+    private static final Attributes.Name SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME =
+            new Attributes.Name("X-Android-APK-Signed");
+
+    /**
+     * Signer configuration.
+     */
+    public static class SignerConfig {
+        /** Name. */
+        public String name;
+
+        /** Private key. */
+        public PrivateKey privateKey;
+
+        /**
+         * Certificates, with the first certificate containing the public key corresponding to
+         * {@link #privateKey}.
+         */
+        public List<X509Certificate> certificates;
+
+        /**
+         * Digest algorithm used for the signature.
+         */
+        public DigestAlgorithm signatureDigestAlgorithm;
+
+        /**
+         * Digest algorithm used for digests of JAR entries and MANIFEST.MF.
+         */
+        public DigestAlgorithm contentDigestAlgorithm;
+    }
+
+    /** Hidden constructor to prevent instantiation. */
+    private V1SchemeSigner() {}
+
+    /**
+     * Gets the JAR signing digest algorithm to be used for signing an APK using the provided key.
+     *
+     * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see
+     *        AndroidManifest.xml minSdkVersion attribute)
+     *
+     * @throws InvalidKeyException if the provided key is not suitable for signing APKs using
+     *         JAR signing (aka v1 signature scheme)
+     */
+    public static DigestAlgorithm getSuggestedSignatureDigestAlgorithm(
+            PublicKey signingKey, int minSdkVersion) throws InvalidKeyException {
+        String keyAlgorithm = signingKey.getAlgorithm();
+        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
+            // Prior to API Level 18, only SHA-1 can be used with RSA.
+            if (minSdkVersion < 18) {
+                return DigestAlgorithm.SHA1;
+            }
+            return DigestAlgorithm.SHA256;
+        } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
+            // Prior to API Level 21, only SHA-1 can be used with DSA
+            if (minSdkVersion < 21) {
+                return DigestAlgorithm.SHA1;
+            } else {
+                return DigestAlgorithm.SHA256;
+            }
+        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
+            if (minSdkVersion < 18) {
+                throw new InvalidKeyException(
+                        "ECDSA signatures only supported for minSdkVersion 18 and higher");
+            }
+            // Prior to API Level 21, only SHA-1 can be used with ECDSA
+            if (minSdkVersion < 21) {
+                return DigestAlgorithm.SHA1;
+            } else {
+                return DigestAlgorithm.SHA256;
+            }
+        } else {
+            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    /**
+     * Returns the JAR signing digest algorithm to be used for JAR entry digests.
+     *
+     * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see
+     *        AndroidManifest.xml minSdkVersion attribute)
+     */
+    public static DigestAlgorithm getSuggestedContentDigestAlgorithm(int minSdkVersion) {
+        return (minSdkVersion >= 18) ? DigestAlgorithm.SHA256 : DigestAlgorithm.SHA1;
+    }
+
+    /**
+     * Returns a new {@link MessageDigest} instance corresponding to the provided digest algorithm.
+     */
+    public static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) {
+        String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm();
+        try {
+            return MessageDigest.getInstance(jcaAlgorithm);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("Failed to obtain " + jcaAlgorithm + " MessageDigest", e);
+        }
+    }
+
+    /**
+     * Returns {@code true} if the provided JAR entry must be mentioned in signed JAR archive's
+     * manifest.
+     */
+    public static boolean isJarEntryDigestNeededInManifest(String entryName) {
+        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File
+
+        // Entries outside of META-INF must be listed in the manifest.
+        if (!entryName.startsWith("META-INF/")) {
+            return true;
+        }
+        // Entries in subdirectories of META-INF must be listed in the manifest.
+        if (entryName.indexOf('/', "META-INF/".length()) != -1) {
+            return true;
+        }
+
+        // Ignored file names (case-insensitive) in META-INF directory:
+        //   MANIFEST.MF
+        //   *.SF
+        //   *.RSA
+        //   *.DSA
+        //   *.EC
+        //   SIG-*
+        String fileNameLowerCase =
+                entryName.substring("META-INF/".length()).toLowerCase(Locale.US);
+        if (("manifest.mf".equals(fileNameLowerCase))
+                || (fileNameLowerCase.endsWith(".sf"))
+                || (fileNameLowerCase.endsWith(".rsa"))
+                || (fileNameLowerCase.endsWith(".dsa"))
+                || (fileNameLowerCase.endsWith(".ec"))
+                || (fileNameLowerCase.startsWith("sig-"))) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of
+     * JAR entries which need to be added to the APK as part of the signature.
+     *
+     * @param signerConfigs signer configurations, one for each signer. At least one signer config
+     *        must be provided.
+     *
+     * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
+     *         cannot be used in general
+     * @throws SignatureException if an error occurs when computing digests of generating
+     *         signatures
+     */
+    public static List<Pair<String, byte[]>> sign(
+            List<SignerConfig> signerConfigs,
+            DigestAlgorithm jarEntryDigestAlgorithm,
+            Map<String, byte[]> jarEntryDigests,
+            List<Integer> apkSigningSchemeIds,
+            byte[] sourceManifestBytes)
+                    throws InvalidKeyException, CertificateEncodingException, SignatureException {
+        if (signerConfigs.isEmpty()) {
+            throw new IllegalArgumentException("At least one signer config must be provided");
+        }
+        OutputManifestFile manifest =
+                generateManifestFile(jarEntryDigestAlgorithm, jarEntryDigests, sourceManifestBytes);
+
+        return signManifest(signerConfigs, jarEntryDigestAlgorithm, apkSigningSchemeIds, manifest);
+    }
+
+    /**
+     * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of
+     * JAR entries which need to be added to the APK as part of the signature.
+     *
+     * @param signerConfigs signer configurations, one for each signer. At least one signer config
+     *        must be provided.
+     *
+     * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
+     *         cannot be used in general
+     * @throws SignatureException if an error occurs when computing digests of generating
+     *         signatures
+     */
+    public static List<Pair<String, byte[]>> signManifest(
+            List<SignerConfig> signerConfigs,
+            DigestAlgorithm digestAlgorithm,
+            List<Integer> apkSigningSchemeIds,
+            OutputManifestFile manifest)
+                    throws InvalidKeyException, CertificateEncodingException, SignatureException {
+        if (signerConfigs.isEmpty()) {
+            throw new IllegalArgumentException("At least one signer config must be provided");
+        }
+
+        // For each signer output .SF and .(RSA|DSA|EC) file, then output MANIFEST.MF.
+        List<Pair<String, byte[]>> signatureJarEntries =
+                new ArrayList<>(2 * signerConfigs.size() + 1);
+        byte[] sfBytes =
+                generateSignatureFile(apkSigningSchemeIds, digestAlgorithm, manifest);
+        for (SignerConfig signerConfig : signerConfigs) {
+            String signerName = signerConfig.name;
+            byte[] signatureBlock;
+            try {
+                signatureBlock = generateSignatureBlock(signerConfig, sfBytes);
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeyException(
+                        "Failed to sign using signer \"" + signerName + "\"", e);
+            } catch (CertificateEncodingException e) {
+                throw new CertificateEncodingException(
+                        "Failed to sign using signer \"" + signerName + "\"", e);
+            } catch (SignatureException e) {
+                throw new SignatureException(
+                        "Failed to sign using signer \"" + signerName + "\"", e);
+            }
+            signatureJarEntries.add(Pair.of("META-INF/" + signerName + ".SF", sfBytes));
+            PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
+            String signatureBlockFileName =
+                    "META-INF/" + signerName + "."
+                            + publicKey.getAlgorithm().toUpperCase(Locale.US);
+            signatureJarEntries.add(
+                    Pair.of(signatureBlockFileName, signatureBlock));
+        }
+        signatureJarEntries.add(Pair.of(MANIFEST_ENTRY_NAME, manifest.contents));
+        return signatureJarEntries;
+    }
+
+    /**
+     * Returns the names of JAR entries which this signer will produce as part of v1 signature.
+     */
+    public static Set<String> getOutputEntryNames(List<SignerConfig> signerConfigs) {
+        Set<String> result = new HashSet<>(2 * signerConfigs.size() + 1);
+        for (SignerConfig signerConfig : signerConfigs) {
+            String signerName = signerConfig.name;
+            result.add("META-INF/" + signerName + ".SF");
+            PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
+            String signatureBlockFileName =
+                    "META-INF/" + signerName + "."
+                            + publicKey.getAlgorithm().toUpperCase(Locale.US);
+            result.add(signatureBlockFileName);
+        }
+        result.add(MANIFEST_ENTRY_NAME);
+        return result;
+    }
+
+    /**
+     * Generated and returns the {@code META-INF/MANIFEST.MF} file based on the provided (optional)
+     * input {@code MANIFEST.MF} and digests of JAR entries covered by the manifest.
+     */
+    public static OutputManifestFile generateManifestFile(
+            DigestAlgorithm jarEntryDigestAlgorithm,
+            Map<String, byte[]> jarEntryDigests,
+            byte[] sourceManifestBytes) {
+        Manifest sourceManifest = null;
+        if (sourceManifestBytes != null) {
+            try {
+                sourceManifest = new Manifest(new ByteArrayInputStream(sourceManifestBytes));
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Failed to parse source MANIFEST.MF", e);
+            }
+        }
+        ByteArrayOutputStream manifestOut = new ByteArrayOutputStream();
+        Attributes mainAttrs = new Attributes();
+        // Copy the main section from the source manifest (if provided). Otherwise use defaults.
+        if (sourceManifest != null) {
+            mainAttrs.putAll(sourceManifest.getMainAttributes());
+        } else {
+            mainAttrs.put(Attributes.Name.MANIFEST_VERSION, ATTRIBUTE_VALUE_MANIFEST_VERSION);
+            mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY);
+        }
+
+        try {
+            ManifestWriter.writeMainSection(manifestOut, mainAttrs);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e);
+        }
+
+        List<String> sortedEntryNames = new ArrayList<>(jarEntryDigests.keySet());
+        Collections.sort(sortedEntryNames);
+        SortedMap<String, byte[]> invidualSectionsContents = new TreeMap<>();
+        String entryDigestAttributeName = getEntryDigestAttributeName(jarEntryDigestAlgorithm);
+        for (String entryName : sortedEntryNames) {
+            byte[] entryDigest = jarEntryDigests.get(entryName);
+            Attributes entryAttrs = new Attributes();
+            entryAttrs.putValue(
+                    entryDigestAttributeName,
+                    Base64.getEncoder().encodeToString(entryDigest));
+            ByteArrayOutputStream sectionOut = new ByteArrayOutputStream();
+            byte[] sectionBytes;
+            try {
+                ManifestWriter.writeIndividualSection(sectionOut, entryName, entryAttrs);
+                sectionBytes = sectionOut.toByteArray();
+                manifestOut.write(sectionBytes);
+            } catch (IOException e) {
+                throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e);
+            }
+            invidualSectionsContents.put(entryName, sectionBytes);
+        }
+
+        OutputManifestFile result = new OutputManifestFile();
+        result.contents = manifestOut.toByteArray();
+        result.mainSectionAttributes = mainAttrs;
+        result.individualSectionsContents = invidualSectionsContents;
+        return result;
+    }
+
+    public static class OutputManifestFile {
+        public byte[] contents;
+        public SortedMap<String, byte[]> individualSectionsContents;
+        public Attributes mainSectionAttributes;
+    }
+
+    private static byte[] generateSignatureFile(
+            List<Integer> apkSignatureSchemeIds,
+            DigestAlgorithm manifestDigestAlgorithm,
+            OutputManifestFile manifest) {
+        Manifest sf = new Manifest();
+        Attributes mainAttrs = sf.getMainAttributes();
+        mainAttrs.put(Attributes.Name.SIGNATURE_VERSION, ATTRIBUTE_VALUE_SIGNATURE_VERSION);
+        mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY);
+        if (!apkSignatureSchemeIds.isEmpty()) {
+            // Add APK Signature Scheme v2 (and newer) signature stripping protection.
+            // This attribute indicates that this APK is supposed to have been signed using one or
+            // more APK-specific signature schemes in addition to the standard JAR signature scheme
+            // used by this code. APK signature verifier should reject the APK if it does not
+            // contain a signature for the signature scheme the verifier prefers out of this set.
+            StringBuilder attrValue = new StringBuilder();
+            for (int id : apkSignatureSchemeIds) {
+                if (attrValue.length() > 0) {
+                    attrValue.append(", ");
+                }
+                attrValue.append(String.valueOf(id));
+            }
+            mainAttrs.put(
+                    SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME,
+                    attrValue.toString());
+        }
+
+        // Add main attribute containing the digest of MANIFEST.MF.
+        MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm);
+        mainAttrs.putValue(
+                getManifestDigestAttributeName(manifestDigestAlgorithm),
+                Base64.getEncoder().encodeToString(md.digest(manifest.contents)));
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            SignatureFileWriter.writeMainSection(out, mainAttrs);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to write in-memory .SF file", e);
+        }
+        String entryDigestAttributeName = getEntryDigestAttributeName(manifestDigestAlgorithm);
+        for (Map.Entry<String, byte[]> manifestSection
+                : manifest.individualSectionsContents.entrySet()) {
+            String sectionName = manifestSection.getKey();
+            byte[] sectionContents = manifestSection.getValue();
+            byte[] sectionDigest = md.digest(sectionContents);
+            Attributes attrs = new Attributes();
+            attrs.putValue(
+                    entryDigestAttributeName,
+                    Base64.getEncoder().encodeToString(sectionDigest));
+
+            try {
+                SignatureFileWriter.writeIndividualSection(out, sectionName, attrs);
+            } catch (IOException e) {
+                throw new RuntimeException("Failed to write in-memory .SF file", e);
+            }
+        }
+
+        // A bug in the java.util.jar implementation of Android platforms up to version 1.6 will
+        // cause a spurious IOException to be thrown if the length of the signature file is a
+        // multiple of 1024 bytes. As a workaround, add an extra CRLF in this case.
+        if ((out.size() > 0) && ((out.size() % 1024) == 0)) {
+            try {
+                SignatureFileWriter.writeSectionDelimiter(out);
+            } catch (IOException e) {
+                throw new RuntimeException("Failed to write to ByteArrayOutputStream", e);
+            }
+        }
+
+        return out.toByteArray();
+    }
+
+    private static byte[] generateSignatureBlock(
+            SignerConfig signerConfig, byte[] signatureFileBytes)
+                    throws InvalidKeyException, CertificateEncodingException, SignatureException {
+        JcaCertStore certs = new JcaCertStore(signerConfig.certificates);
+        X509Certificate signerCert = signerConfig.certificates.get(0);
+        String jcaSignatureAlgorithm =
+                getJcaSignatureAlgorithm(
+                        signerCert.getPublicKey(), signerConfig.signatureDigestAlgorithm);
+        try {
+            ContentSigner signer =
+                    new JcaContentSignerBuilder(jcaSignatureAlgorithm)
+                    .build(signerConfig.privateKey);
+            CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
+            gen.addSignerInfoGenerator(
+                    new JcaSignerInfoGeneratorBuilder(
+                            new JcaDigestCalculatorProviderBuilder().build())
+                    .setDirectSignature(true)
+                    .build(signer, signerCert));
+            gen.addCertificates(certs);
+
+            CMSSignedData sigData =
+                    gen.generate(new CMSProcessableByteArray(signatureFileBytes), false);
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            try (ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded())) {
+                DEROutputStream dos = new DEROutputStream(out);
+                dos.writeObject(asn1.readObject());
+            }
+            return out.toByteArray();
+        } catch (OperatorCreationException | CMSException | IOException e) {
+            throw new SignatureException("Failed to generate signature", e);
+        }
+    }
+
+    private static String getEntryDigestAttributeName(DigestAlgorithm digestAlgorithm) {
+        switch (digestAlgorithm) {
+            case SHA1:
+                return "SHA1-Digest";
+            case SHA256:
+                return "SHA-256-Digest";
+            default:
+                throw new IllegalArgumentException(
+                        "Unexpected content digest algorithm: " + digestAlgorithm);
+        }
+    }
+
+    private static String getManifestDigestAttributeName(DigestAlgorithm digestAlgorithm) {
+        switch (digestAlgorithm) {
+            case SHA1:
+                return "SHA1-Digest-Manifest";
+            case SHA256:
+                return "SHA-256-Digest-Manifest";
+            default:
+                throw new IllegalArgumentException(
+                        "Unexpected content digest algorithm: " + digestAlgorithm);
+        }
+    }
+
+    private static String getJcaSignatureAlgorithm(
+            PublicKey publicKey, DigestAlgorithm digestAlgorithm) throws InvalidKeyException {
+        String keyAlgorithm = publicKey.getAlgorithm();
+        String digestPrefixForSigAlg;
+        switch (digestAlgorithm) {
+            case SHA1:
+                digestPrefixForSigAlg = "SHA1";
+                break;
+            case SHA256:
+                digestPrefixForSigAlg = "SHA256";
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "Unexpected digest algorithm: " + digestAlgorithm);
+        }
+        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
+            return digestPrefixForSigAlg + "withRSA";
+        } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
+            return digestPrefixForSigAlg + "withDSA";
+        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
+            return digestPrefixForSigAlg + "withECDSA";
+        } else {
+            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java
new file mode 100644
index 0000000..449953a
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.jar;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.jar.Attributes;
+
+/**
+ * Producer of {@code META-INF/MANIFEST.MF} file.
+ */
+public abstract class ManifestWriter {
+
+    private static final byte[] CRLF = new byte[] {'\r', '\n'};
+    private static final int MAX_LINE_LENGTH = 70;
+
+    private ManifestWriter() {}
+
+    public static void writeMainSection(OutputStream out, Attributes attributes)
+            throws IOException {
+
+        // Main section must start with the Manifest-Version attribute.
+        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File.
+        String manifestVersion = attributes.getValue(Attributes.Name.MANIFEST_VERSION);
+        if (manifestVersion == null) {
+            throw new IllegalArgumentException(
+                    "Mandatory " + Attributes.Name.MANIFEST_VERSION + " attribute missing");
+        }
+        writeAttribute(out, Attributes.Name.MANIFEST_VERSION, manifestVersion);
+
+        if (attributes.size() > 1) {
+            SortedMap<String, String> namedAttributes = getAttributesSortedByName(attributes);
+            namedAttributes.remove(Attributes.Name.MANIFEST_VERSION.toString());
+            writeAttributes(out, namedAttributes);
+        }
+        writeSectionDelimiter(out);
+    }
+
+    public static void writeIndividualSection(OutputStream out, String name, Attributes attributes)
+            throws IOException {
+        writeAttribute(out, "Name", name);
+
+        if (!attributes.isEmpty()) {
+            writeAttributes(out, getAttributesSortedByName(attributes));
+        }
+        writeSectionDelimiter(out);
+    }
+
+    static void writeSectionDelimiter(OutputStream out) throws IOException {
+        out.write(CRLF);
+    }
+
+    static void writeAttribute(OutputStream  out, Attributes.Name name, String value)
+            throws IOException {
+        writeAttribute(out, name.toString(), value);
+    }
+
+    private static void writeAttribute(OutputStream  out, String name, String value)
+            throws IOException {
+        writeLine(out, name + ": " + value);
+    }
+
+    private static void writeLine(OutputStream  out, String line) throws IOException {
+        byte[] lineBytes = line.getBytes("UTF-8");
+        int offset = 0;
+        int remaining = lineBytes.length;
+        boolean firstLine = true;
+        while (remaining > 0) {
+            int chunkLength;
+            if (firstLine) {
+                // First line
+                chunkLength = Math.min(remaining, MAX_LINE_LENGTH);
+            } else {
+                // Continuation line
+                out.write(CRLF);
+                out.write(' ');
+                chunkLength = Math.min(remaining, MAX_LINE_LENGTH - 1);
+            }
+            out.write(lineBytes, offset, chunkLength);
+            offset += chunkLength;
+            remaining -= chunkLength;
+            firstLine = false;
+        }
+        out.write(CRLF);
+    }
+
+    static SortedMap<String, String> getAttributesSortedByName(Attributes attributes) {
+        Set<Map.Entry<Object, Object>> attributesEntries = attributes.entrySet();
+        SortedMap<String, String> namedAttributes = new TreeMap<String, String>();
+        for (Map.Entry<Object, Object> attribute : attributesEntries) {
+            String attrName = attribute.getKey().toString();
+            String attrValue = attribute.getValue().toString();
+            namedAttributes.put(attrName, attrValue);
+        }
+        return namedAttributes;
+    }
+
+    static void writeAttributes(
+            OutputStream out, SortedMap<String, String> attributesSortedByName) throws IOException {
+        for (Map.Entry<String, String> attribute : attributesSortedByName.entrySet()) {
+            String attrName = attribute.getKey();
+            String attrValue = attribute.getValue();
+            writeAttribute(out, attrName, attrValue);
+        }
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java
new file mode 100644
index 0000000..9cd25f3
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.jar;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.SortedMap;
+import java.util.jar.Attributes;
+
+/**
+ * Producer of JAR signature file ({@code *.SF}).
+ */
+public abstract class SignatureFileWriter {
+    private SignatureFileWriter() {}
+
+    public static void writeMainSection(OutputStream out, Attributes attributes)
+            throws IOException {
+
+        // Main section must start with the Signature-Version attribute.
+        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File.
+        String signatureVersion = attributes.getValue(Attributes.Name.SIGNATURE_VERSION);
+        if (signatureVersion == null) {
+            throw new IllegalArgumentException(
+                    "Mandatory " + Attributes.Name.SIGNATURE_VERSION + " attribute missing");
+        }
+        ManifestWriter.writeAttribute(out, Attributes.Name.SIGNATURE_VERSION, signatureVersion);
+
+        if (attributes.size() > 1) {
+            SortedMap<String, String> namedAttributes =
+                    ManifestWriter.getAttributesSortedByName(attributes);
+            namedAttributes.remove(Attributes.Name.SIGNATURE_VERSION.toString());
+            ManifestWriter.writeAttributes(out, namedAttributes);
+        }
+        writeSectionDelimiter(out);
+    }
+
+    public static void writeIndividualSection(OutputStream out, String name, Attributes attributes)
+            throws IOException {
+        ManifestWriter.writeIndividualSection(out, name, attributes);
+    }
+
+    public static void writeSectionDelimiter(OutputStream out) throws IOException {
+        ManifestWriter.writeSectionDelimiter(out);
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java
new file mode 100644
index 0000000..d59af41
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.util;
+
+/**
+ * Pair of two elements.
+ */
+public final class Pair<A, B> {
+    private final A mFirst;
+    private final B mSecond;
+
+    private Pair(A first, B second) {
+        mFirst = first;
+        mSecond = second;
+    }
+
+    public static <A, B> Pair<A, B> of(A first, B second) {
+        return new Pair<A, B>(first, second);
+    }
+
+    public A getFirst() {
+        return mFirst;
+    }
+
+    public B getSecond() {
+        return mSecond;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode());
+        result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        @SuppressWarnings("rawtypes")
+        Pair other = (Pair) obj;
+        if (mFirst == null) {
+            if (other.mFirst != null) {
+                return false;
+            }
+        } else if (!mFirst.equals(other.mFirst)) {
+            return false;
+        }
+        if (mSecond == null) {
+            if (other.mSecond != null) {
+                return false;
+            }
+        } else if (!mSecond.equals(other.mSecond)) {
+            return false;
+        }
+        return true;
+    }
+}
