First, generate MANIFEST. MF file
For each file in the APK package (non-directory and non-signed), Generate SHA1 summary information. This information is then BASE64 encoded. Manifest Manifest = adddigeststomanifest (Inputjar);
Will get the information above. Write Manifest.mf je = new Jarentry (jarfile.manifest_name); Je.settime (timestamp); Outputjar.putnextentry (JE); Manifest.write (Outputjar);
Second, generate cert.sf file
Je = new Jarentry (cert_sf_name); Je.settime (timestamp); Outputjar.putnextentry (JE); Bytearrayoutputstream BAOs = new Bytearrayoutputstream (); Writesignaturefile (Manifest, BAOs); byte[] Signeddata = Baos.tobytearray (); Outputjar.write (Signeddata);
theWholeMANIFEST. MFmakeSHA1calculations. and deposit summary information intoCERT. SFin. Then use SHA1 for all summary information that was previously calculatedre-count
The result is also written to CERT. In SF , Key code in writesignaturefile (Manifest, BAOs),
/** Write A. SF file with a digest of the specified manifest. */private static void Writesignaturefile (Manifest Manifest, outputstream out) throws IOException, Generalsecuri tyexception {Manifest SF = new Manifest (); Attributes main = Sf.getmainattributes (); Main.putvalue ("Signature-version", "1.0"); Main.putvalue ("created-by", "1.0 (Android signapk)"); MessageDigest MD = messagedigest.getinstance ("SHA1"); PrintStream print = new PrintStream (new Digestoutputstream (New Bytearrayoutputstream (), MD), True, "UTF-8"); Digest of the entire manifest manifest.write (print); Print.flush (); Main.putvalue ("Sha1-digest-manifest", New String (Base64.encode (Md.digest ()), "ASCII")); map<string, attributes> entries = Manifest.getentries (); For (map.entry<string, attributes> entry:entries.entrySet ()) {//Digest of the manifest sTanza for this entry. Print.print ("Name:" + entry.getkey () + "\ r \ n"); For (Map.entry<object, object> att:entry.getValue (). EntrySet ()) {Print.print (Att.getkey () + ":" + Att.getvalue () + "\ r \ n"); } print.print ("\ r \ n"); Print.flush (); Attributes sfattr = new Attributes (); Sfattr.putvalue ("Sha1-digest", New String (Base64.encode (Md.digest ()), "ASCII")); Sf.getentries (). Put (Entry.getkey (), sfattr); } countoutputstream cout = new Countoutputstream (out); Sf.write (cout); A bug in the Java.util.jar implementation of Android platforms//up to version 1.6 would cause a spurious ioexce Ption to being thrown//if the length of the signature file is a multiple of 1024x768 bytes. As a workaround, add an extra CRLF in the case. if ((cout.size ()%) = = 0) {cout.write (' \ R '); Cout.writE (' \ n '); } }
Iii. generating Cert.rsa files
<span style= "White-space:pre" ></span>je = new Jarentry (cert_rsa_name); Je.settime (timestamp); Outputjar.putnextentry (JE); Writesignatureblock (New Cmsprocessablebytearray (Signeddata), PublicKey, Privatekey, Outputjar);
key code in writesignatureblock (New Cmsprocessablebytearray (signeddata)
/** sign data and write the digital signature to ' out '. */private static void Writesignatureblock (Cmstypeddata data, X509Certificate publickey, Privatekey Privatekey, OutputStream out) throws IOException, Certificateencodingexception, Operatorcre Ationexception, cmsexception {arraylist<x509certificate> certlist = new Arraylist<x509certi Ficate> (1); Certlist.add (PublicKey); Jcacertstore certs = new Jcacertstore (certlist); Cmssigneddatagenerator Gen = new Cmssigneddatagenerator (); Contentsigner Sha1signer = new Jcacontentsignerbuilder ("Sha1withrsa"). Setprovider (Sbouncycastleprovider) . Build (Privatekey); Gen.addsignerinfogenerator (New Jcasignerinfogeneratorbuilder (New Jcadigestcalculatorproviderbu Ilder (). Setprovider (Sbouncycastleprovider). Build ()). Setdirectsignature (True) . Build (Sha1signer, PublicKey)); Gen.addcertificates (certs); Cmssigneddata Sigdata = gen.generate (data, false); Asn1inputstream ASN1 = new Asn1inputstream (sigdata.getencoded ()); Deroutputstream dos = new Deroutputstream (out); Dos.writeobject (Asn1.readobject ()); }
put the previously generated CERT. SF file, which computes the signature with a private key, and then writes the signature and public key information to the CERT. saved in RSA.