/// <summary> /// Add a Digest entry /// </summary> public byte[] GetEntryAttributes(string name, Stream stream) { var builder = new MetaInfManifestBuilder(true); builder.AddSha1Digest(name, stream); return(builder.ToArray()); }
/// <summary> /// Compile the given XML file to a binary XML file in the given output folder. /// </summary> public void Build() { #if DEBUG //Debugger.Launch(); #endif // Prepare folder var outputFolder = Path.GetDirectoryName(path); if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } // Sign apk? const bool sign = true; // Collect entries var entries = new List <ApkEntry>(); entries.Add(new ApkEntry("AndroidManifest.xml", ManifestPath)); entries.AddRange(DexFiles.Select(dexFile => new ApkEntry(Path.GetFileName(dexFile), dexFile))); // Collect map files var mapFiles = MapFiles.Select(p => new MapFile(p)).ToList(); // Collect resource files var resourceEntries = new List <ApkEntry>(); if (!string.IsNullOrEmpty(ResourcesFolder)) { CollectResources(resourceEntries, ResourcesFolder, ResourcesFolder); entries.AddRange(resourceEntries); } // Collect embedded resources as assets foreach (var assembly in Assemblies) { var assets = new List <ApkEntry>(); CollectAssets(assets, assembly); entries.AddRange(assets); } // Collect native code libs CollectNativeCodeLibs(entries); // Load free apps key (if any) string freeAppKey = null; if (!string.IsNullOrEmpty(FreeAppsKeyPath)) { freeAppKey = File.ReadAllText(FreeAppsKeyPath); } // Build ZIP var manifest = new MetaInfManifestBuilder(); var signature = new MetaInfCertSfBuilder(manifest); var rsa = new MetaInfCertRsaBuilder(signature, PfxFile, PfxPassword, CertificateThumbprint, freeAppKey, PackageName); // Build signatures if (sign) { foreach (var entry in entries) { manifest.AddSha1Digest(entry.Name, entry.Data); signature.AddSha1Digest(entry.Name, entry.Data); } } // Create zip string md5FingerPrint = null; string sha1FingerPrint = null; using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) { using (var zipStream = new ZipOutputStream(fileStream) { UseZip64 = UseZip64.Off }) { zipStream.SetLevel(9); zipStream.PutNextEntry(new ZipEntry("META-INF/MANIFEST.MF") { CompressionMethod = CompressionMethod.Deflated }); manifest.WriteTo(zipStream); zipStream.CloseEntry(); if (sign) { zipStream.PutNextEntry(new ZipEntry("META-INF/LE-C0FC2.SF") { CompressionMethod = CompressionMethod.Deflated }); signature.WriteTo(zipStream); zipStream.CloseEntry(); zipStream.PutNextEntry(new ZipEntry("META-INF/LE-C0FC2.RSA") { CompressionMethod = CompressionMethod.Deflated }); rsa.WriteTo(zipStream, out md5FingerPrint, out sha1FingerPrint); zipStream.CloseEntry(); } foreach (var entry in entries) { var entryName = entry.Name.Replace('\\', '/'); zipStream.PutNextEntry(new ZipEntry(entryName) { CompressionMethod = GetCompressionMethod(entryName) }); entry.WriteTo(zipStream); zipStream.CloseEntry(); } } } // Save MD5 fingerprint var md5FingerPrintPath = Path.ChangeExtension(path, ".md5"); File.WriteAllText(md5FingerPrintPath, md5FingerPrint ?? string.Empty); // Save SHA1 fingerprint var sha1FingerPrintPath = Path.ChangeExtension(path, ".sha1"); File.WriteAllText(sha1FingerPrintPath, sha1FingerPrint ?? string.Empty); // Merge map files var mapFile = MergeMapFiles(mapFiles); mapFile.Save(MapFilePath); #if DEBUG // Create RSA using ( var fileStream = new FileStream(Path.Combine(outputFolder, "CERT.RSA"), FileMode.Create, FileAccess.Write)) { rsa.WriteTo(fileStream, out md5FingerPrint, out sha1FingerPrint); } #endif }
/// <summary> /// Add a Digest entry /// </summary> public byte[] GetEntryAttributes(string name, Stream stream) { var builder = new MetaInfManifestBuilder(true); builder.AddSha1Digest(name, stream); return builder.ToArray(); }
/// <summary> /// Compile the given XML file to a binary XML file in the given output folder. /// </summary> public void Build() { #if DEBUG //Debugger.Launch(); #endif // Prepare folder var outputFolder = Path.GetDirectoryName(path); if (!Directory.Exists(outputFolder)) Directory.CreateDirectory(outputFolder); // Sign apk? const bool sign = true; // Collect entries var entries = new List<ApkEntry>(); entries.Add(new ApkEntry("AndroidManifest.xml", ManifestPath)); entries.AddRange(DexFiles.Select(dexFile => new ApkEntry(Path.GetFileName(dexFile), dexFile))); // Collect map files var mapFiles = MapFiles.Select(p => new MapFile(p)).ToList(); // Collect resource files var resourceEntries = new List<ApkEntry>(); if (!string.IsNullOrEmpty(ResourcesFolder)) { CollectResources(resourceEntries, ResourcesFolder, ResourcesFolder); entries.AddRange(resourceEntries); } // Collect embedded resources as assets foreach (var assembly in Assemblies) { var assets = new List<ApkEntry>(); CollectAssets(assets, assembly); entries.AddRange(assets); } // Collect native code libs CollectNativeCodeLibs(entries); // Load free apps key (if any) string freeAppKey = null; if (!string.IsNullOrEmpty(FreeAppsKeyPath)) { freeAppKey = File.ReadAllText(FreeAppsKeyPath); } // Build ZIP var manifest = new MetaInfManifestBuilder(); var signature = new MetaInfCertSfBuilder(manifest); var rsa = new MetaInfCertRsaBuilder(signature, PfxFile, PfxPassword, CertificateThumbprint, freeAppKey, PackageName); // Build signatures if (sign) { foreach (var entry in entries) { manifest.AddSha1Digest(entry.Name, entry.Data); signature.AddSha1Digest(entry.Name, entry.Data); } } // Create zip string md5FingerPrint = null; string sha1FingerPrint = null; using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) { using (var zipStream = new ZipOutputStream(fileStream) {UseZip64 = UseZip64.Off}) { zipStream.SetLevel(9); zipStream.PutNextEntry(new ZipEntry("META-INF/MANIFEST.MF") {CompressionMethod = CompressionMethod.Deflated}); manifest.WriteTo(zipStream); zipStream.CloseEntry(); if (sign) { zipStream.PutNextEntry(new ZipEntry("META-INF/LE-C0FC2.SF") {CompressionMethod = CompressionMethod.Deflated}); signature.WriteTo(zipStream); zipStream.CloseEntry(); zipStream.PutNextEntry(new ZipEntry("META-INF/LE-C0FC2.RSA") {CompressionMethod = CompressionMethod.Deflated}); rsa.WriteTo(zipStream, out md5FingerPrint, out sha1FingerPrint); zipStream.CloseEntry(); } foreach (var entry in entries) { var entryName = entry.Name.Replace('\\', '/'); zipStream.PutNextEntry(new ZipEntry(entryName) { CompressionMethod = GetCompressionMethod(entryName) }); entry.WriteTo(zipStream); zipStream.CloseEntry(); } } } // Save MD5 fingerprint var md5FingerPrintPath = Path.ChangeExtension(path, ".md5"); File.WriteAllText(md5FingerPrintPath, md5FingerPrint ?? string.Empty); // Save SHA1 fingerprint var sha1FingerPrintPath = Path.ChangeExtension(path, ".sha1"); File.WriteAllText(sha1FingerPrintPath, sha1FingerPrint ?? string.Empty); // Merge map files var mapFile = MergeMapFiles(mapFiles); mapFile.Save(MapFilePath); #if DEBUG // Create RSA using ( var fileStream = new FileStream(Path.Combine(outputFolder, "CERT.RSA"), FileMode.Create, FileAccess.Write)) { rsa.WriteTo(fileStream, out md5FingerPrint, out sha1FingerPrint); } #endif }