Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
325d9a0b
Commit
325d9a0b
authored
Oct 20, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generate keys for signing hidden Magisk Manager
parent
a02493fb
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
196 additions
and
42 deletions
+196
-42
Config.kt
app/src/main/java/com/topjohnwu/magisk/Config.kt
+4
-2
Keygen.kt
app/src/main/java/com/topjohnwu/magisk/utils/Keygen.kt
+133
-0
PatchAPK.kt
app/src/main/java/com/topjohnwu/magisk/utils/PatchAPK.kt
+1
-1
CryptoUtils.java
signing/src/main/java/com/topjohnwu/signing/CryptoUtils.java
+3
-3
SignAPK.java
signing/src/main/java/com/topjohnwu/signing/SignAPK.java
+12
-29
ZipSigner.java
signing/src/main/java/com/topjohnwu/signing/ZipSigner.java
+43
-7
No files found.
app/src/main/java/com/topjohnwu/magisk/Config.kt
View file @
325d9a0b
...
@@ -32,8 +32,9 @@ object Config : PreferenceModel, DBConfig {
...
@@ -32,8 +32,9 @@ object Config : PreferenceModel, DBConfig {
const
val
ROOT_ACCESS
=
"root_access"
const
val
ROOT_ACCESS
=
"root_access"
const
val
SU_MULTIUSER_MODE
=
"multiuser_mode"
const
val
SU_MULTIUSER_MODE
=
"multiuser_mode"
const
val
SU_MNT_NS
=
"mnt_ns"
const
val
SU_MNT_NS
=
"mnt_ns"
const
val
SU_MANAGER
=
"requester"
const
val
SU_FINGERPRINT
=
"su_fingerprint"
const
val
SU_FINGERPRINT
=
"su_fingerprint"
const
val
SU_MANAGER
=
"requester"
const
val
KEYSTORE
=
"keystore"
// prefs
// prefs
const
val
SU_REQUEST_TIMEOUT
=
"su_request_timeout"
const
val
SU_REQUEST_TIMEOUT
=
"su_request_timeout"
...
@@ -123,6 +124,7 @@ object Config : PreferenceModel, DBConfig {
...
@@ -123,6 +124,7 @@ object Config : PreferenceModel, DBConfig {
var
suMultiuserMode
by
dbSettings
(
Key
.
SU_MULTIUSER_MODE
,
Value
.
MULTIUSER_MODE_OWNER_ONLY
)
var
suMultiuserMode
by
dbSettings
(
Key
.
SU_MULTIUSER_MODE
,
Value
.
MULTIUSER_MODE_OWNER_ONLY
)
var
suFingerprint
by
dbSettings
(
Key
.
SU_FINGERPRINT
,
false
)
var
suFingerprint
by
dbSettings
(
Key
.
SU_FINGERPRINT
,
false
)
var
suManager
by
dbStrings
(
Key
.
SU_MANAGER
,
""
,
true
)
var
suManager
by
dbStrings
(
Key
.
SU_MANAGER
,
""
,
true
)
var
keyStoreRaw
by
dbStrings
(
Key
.
KEYSTORE
,
""
,
true
)
// Always return a path in external storage where we can write
// Always return a path in external storage where we can write
val
downloadDirectory
get
()
=
val
downloadDirectory
get
()
=
...
@@ -205,4 +207,4 @@ object Config : PreferenceModel, DBConfig {
...
@@ -205,4 +207,4 @@ object Config : PreferenceModel, DBConfig {
Shell
.
su
(
"cat $xml > /data/adb/${Const.MANAGER_CONFIGS}"
).
exec
()
Shell
.
su
(
"cat $xml > /data/adb/${Const.MANAGER_CONFIGS}"
).
exec
()
}
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/utils/Keygen.kt
0 → 100644
View file @
325d9a0b
package
com.topjohnwu.magisk.utils
import
android.content.pm.PackageManager
import
android.util.Base64
import
android.util.Base64OutputStream
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.di.koinModules
import
com.topjohnwu.signing.CryptoUtils.readCertificate
import
com.topjohnwu.signing.CryptoUtils.readPrivateKey
import
com.topjohnwu.superuser.internal.InternalUtils
import
org.bouncycastle.asn1.x500.X500Name
import
org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import
org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import
org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
import
org.koin.core.context.GlobalContext
import
org.koin.core.context.startKoin
import
timber.log.Timber
import
java.io.ByteArrayInputStream
import
java.io.ByteArrayOutputStream
import
java.math.BigInteger
import
java.security.KeyPairGenerator
import
java.security.KeyStore
import
java.security.MessageDigest
import
java.security.PrivateKey
import
java.security.cert.X509Certificate
import
java.util.*
import
java.util.zip.GZIPInputStream
import
java.util.zip.GZIPOutputStream
private
interface
CertKeyProvider
{
val
cert
:
X509Certificate
val
key
:
PrivateKey
}
@Suppress
(
"DEPRECATION"
)
object
Keygen
:
CertKeyProvider
{
private
const
val
ALIAS
=
"magisk"
private
val
PASSWORD
=
"magisk"
.
toCharArray
()
private
const
val
TESTKEY_CERT
=
"61ed377e85d386a8dfee6b864bd85b0bfaa5af81"
private
val
start
get
()
=
Calendar
.
getInstance
()
private
val
end
get
()
=
Calendar
.
getInstance
().
apply
{
add
(
Calendar
.
YEAR
,
20
)
}
override
val
cert
get
()
=
provider
.
cert
override
val
key
get
()
=
provider
.
key
private
val
provider
:
CertKeyProvider
class
KeyStoreProvider
:
CertKeyProvider
{
private
val
ks
by
lazy
{
init
()
}
override
val
cert
by
lazy
{
ks
.
getCertificate
(
ALIAS
)
as
X509Certificate
}
override
val
key
by
lazy
{
ks
.
getKey
(
ALIAS
,
PASSWORD
)
as
PrivateKey
}
}
class
TestProvider
:
CertKeyProvider
{
override
val
cert
by
lazy
{
readCertificate
(
javaClass
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
))
}
override
val
key
by
lazy
{
readPrivateKey
(
javaClass
.
getResourceAsStream
(
"/keys/testkey.pk8"
))
}
}
init
{
// This object could possibly be accessed from an external app
// Get context from reflection into Android's framework
val
context
=
InternalUtils
.
getContext
()
val
pm
=
context
.
packageManager
val
info
=
pm
.
getPackageInfo
(
context
.
packageName
,
PackageManager
.
GET_SIGNATURES
)
val
sig
=
info
.
signatures
[
0
]
val
digest
=
MessageDigest
.
getInstance
(
"SHA1"
)
val
chksum
=
digest
.
digest
(
sig
.
toByteArray
())
val
sb
=
StringBuilder
()
for
(
b
in
chksum
)
{
sb
.
append
(
"%02x"
.
format
(
0
xFF
and
b
.
toInt
()))
}
provider
=
if
(
sb
.
toString
()
==
TESTKEY_CERT
)
{
// The app was signed by the test key, continue to use it (legacy mode)
TestProvider
()
}
else
{
KeyStoreProvider
()
}
}
private
fun
init
():
KeyStore
{
GlobalContext
.
getOrNull
()
?:
{
// Invoked externally, do some basic initialization
startKoin
{
modules
(
koinModules
)
}
Timber
.
plant
(
Timber
.
DebugTree
())
}()
val
raw
=
Config
.
keyStoreRaw
val
ks
=
KeyStore
.
getInstance
(
"PKCS12"
)
if
(
raw
.
isEmpty
())
{
ks
.
load
(
null
)
}
else
{
GZIPInputStream
(
ByteArrayInputStream
(
Base64
.
decode
(
raw
,
Base64
.
NO_PADDING
or
Base64
.
NO_WRAP
)
)).
use
{
ks
.
load
(
it
,
PASSWORD
)
}
}
// Keys already exist
if
(
ks
.
containsAlias
(
ALIAS
))
return
ks
// Generate new private key and certificate
val
kp
=
KeyPairGenerator
.
getInstance
(
"RSA"
).
apply
{
initialize
(
2048
)
}.
genKeyPair
()
val
dn
=
X500Name
(
"CN=Magisk"
)
val
builder
=
JcaX509v3CertificateBuilder
(
dn
,
BigInteger
.
valueOf
(
start
.
timeInMillis
),
start
.
time
,
end
.
time
,
dn
,
kp
.
public
)
val
signer
=
JcaContentSignerBuilder
(
"SHA256WithRSA"
).
build
(
kp
.
private
)
val
cert
=
JcaX509CertificateConverter
().
getCertificate
(
builder
.
build
(
signer
))
// Store them into keystore
ks
.
setKeyEntry
(
ALIAS
,
kp
.
private
,
PASSWORD
,
arrayOf
(
cert
))
val
bytes
=
ByteArrayOutputStream
()
GZIPOutputStream
(
Base64OutputStream
(
bytes
,
Base64
.
NO_PADDING
or
Base64
.
NO_WRAP
)).
use
{
ks
.
store
(
it
,
PASSWORD
)
}
Config
.
keyStoreRaw
=
bytes
.
toString
()
return
ks
}
}
app/src/main/java/com/topjohnwu/magisk/utils/PatchAPK.kt
View file @
325d9a0b
...
@@ -107,7 +107,7 @@ object PatchAPK {
...
@@ -107,7 +107,7 @@ object PatchAPK {
// Write apk changes
// Write apk changes
jar
.
getOutputStream
(
je
).
write
(
xml
)
jar
.
getOutputStream
(
je
).
write
(
xml
)
SignAPK
.
sign
(
jar
,
FileOutputStream
(
out
).
buffered
())
SignAPK
.
sign
(
Keygen
.
cert
,
Keygen
.
key
,
jar
,
FileOutputStream
(
out
).
buffered
())
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
Timber
.
e
(
e
)
Timber
.
e
(
e
)
return
false
return
false
...
...
signing/src/main/java/com/topjohnwu/signing/CryptoUtils.java
View file @
325d9a0b
...
@@ -24,7 +24,7 @@ import java.security.spec.PKCS8EncodedKeySpec;
...
@@ -24,7 +24,7 @@ import java.security.spec.PKCS8EncodedKeySpec;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
class
CryptoUtils
{
public
class
CryptoUtils
{
static
final
Map
<
String
,
String
>
ID_TO_ALG
;
static
final
Map
<
String
,
String
>
ID_TO_ALG
;
static
final
Map
<
String
,
String
>
ALG_TO_ID
;
static
final
Map
<
String
,
String
>
ALG_TO_ID
;
...
@@ -81,7 +81,7 @@ class CryptoUtils {
...
@@ -81,7 +81,7 @@ class CryptoUtils {
return
new
AlgorithmIdentifier
(
new
ASN1ObjectIdentifier
(
id
));
return
new
AlgorithmIdentifier
(
new
ASN1ObjectIdentifier
(
id
));
}
}
static
X509Certificate
readCertificate
(
InputStream
input
)
public
static
X509Certificate
readCertificate
(
InputStream
input
)
throws
IOException
,
GeneralSecurityException
{
throws
IOException
,
GeneralSecurityException
{
try
{
try
{
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
...
@@ -92,7 +92,7 @@ class CryptoUtils {
...
@@ -92,7 +92,7 @@ class CryptoUtils {
}
}
/** Read a PKCS#8 format private key. */
/** Read a PKCS#8 format private key. */
static
PrivateKey
readPrivateKey
(
InputStream
input
)
public
static
PrivateKey
readPrivateKey
(
InputStream
input
)
throws
IOException
,
GeneralSecurityException
{
throws
IOException
,
GeneralSecurityException
{
try
{
try
{
ByteArrayStream
buf
=
new
ByteArrayStream
();
ByteArrayStream
buf
=
new
ByteArrayStream
();
...
...
signing/src/main/java/com/topjohnwu/signing/SignAPK.java
View file @
325d9a0b
...
@@ -30,7 +30,6 @@ import java.io.PrintStream;
...
@@ -30,7 +30,6 @@ import java.io.PrintStream;
import
java.io.RandomAccessFile
;
import
java.io.RandomAccessFile
;
import
java.security.DigestOutputStream
;
import
java.security.DigestOutputStream
;
import
java.security.GeneralSecurityException
;
import
java.security.GeneralSecurityException
;
import
java.security.KeyStore
;
import
java.security.MessageDigest
;
import
java.security.MessageDigest
;
import
java.security.PrivateKey
;
import
java.security.PrivateKey
;
import
java.security.cert.CertificateEncodingException
;
import
java.security.cert.CertificateEncodingException
;
...
@@ -61,29 +60,8 @@ public class SignAPK {
...
@@ -61,29 +60,8 @@ public class SignAPK {
private
static
final
int
USE_SHA1
=
1
;
private
static
final
int
USE_SHA1
=
1
;
private
static
final
int
USE_SHA256
=
2
;
private
static
final
int
USE_SHA256
=
2
;
public
static
void
sign
(
JarMap
input
,
OutputStream
output
)
throws
Exception
{
public
static
void
signAndAdjust
(
X509Certificate
cert
,
PrivateKey
key
,
sign
(
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
),
JarMap
input
,
OutputStream
output
)
throws
Exception
{
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
),
input
,
output
);
}
public
static
void
sign
(
InputStream
certIs
,
InputStream
keyIs
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
X509Certificate
cert
=
CryptoUtils
.
readCertificate
(
certIs
);
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIs
);
sign
(
cert
,
key
,
input
,
output
);
}
public
static
void
sign
(
InputStream
jks
,
String
keyStorePass
,
String
alias
,
String
keyPass
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
KeyStore
ks
=
KeyStore
.
getInstance
(
"JKS"
);
ks
.
load
(
jks
,
keyStorePass
.
toCharArray
());
X509Certificate
cert
=
(
X509Certificate
)
ks
.
getCertificate
(
alias
);
PrivateKey
key
=
(
PrivateKey
)
ks
.
getKey
(
alias
,
keyPass
.
toCharArray
());
sign
(
cert
,
key
,
input
,
output
);
}
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
File
temp1
=
File
.
createTempFile
(
"signAPK"
,
null
);
File
temp1
=
File
.
createTempFile
(
"signAPK"
,
null
);
File
temp2
=
File
.
createTempFile
(
"signAPK"
,
null
);
File
temp2
=
File
.
createTempFile
(
"signAPK"
,
null
);
...
@@ -103,6 +81,11 @@ public class SignAPK {
...
@@ -103,6 +81,11 @@ public class SignAPK {
}
}
}
}
public
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
sign
(
cert
,
key
,
input
,
output
,
false
);
}
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
int
hashes
=
0
;
int
hashes
=
0
;
...
@@ -498,11 +481,11 @@ public class SignAPK {
...
@@ -498,11 +481,11 @@ public class SignAPK {
outputStream
.
close
();
outputStream
.
close
();
}
}
private
static
void
signFile
(
Manifest
manifest
,
JarMap
inputJar
,
private
static
void
signFile
(
Manifest
manifest
,
JarMap
inputJar
,
X509Certificate
publicKey
,
PrivateKey
privateKey
,
X509Certificate
cert
,
PrivateKey
privateKey
,
JarOutputStream
outputJar
)
JarOutputStream
outputJar
)
throws
Exception
{
throws
Exception
{
// Assume the certificate is valid for at least an hour.
// Assume the certificate is valid for at least an hour.
long
timestamp
=
publicKey
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
long
timestamp
=
cert
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
// MANIFEST.MF
// MANIFEST.MF
JarEntry
je
=
new
JarEntry
(
JarFile
.
MANIFEST_NAME
);
JarEntry
je
=
new
JarEntry
(
JarFile
.
MANIFEST_NAME
);
je
.
setTime
(
timestamp
);
je
.
setTime
(
timestamp
);
...
@@ -512,15 +495,15 @@ public class SignAPK {
...
@@ -512,15 +495,15 @@ public class SignAPK {
je
.
setTime
(
timestamp
);
je
.
setTime
(
timestamp
);
outputJar
.
putNextEntry
(
je
);
outputJar
.
putNextEntry
(
je
);
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
writeSignatureFile
(
manifest
,
baos
,
getDigestAlgorithm
(
publicKey
));
writeSignatureFile
(
manifest
,
baos
,
getDigestAlgorithm
(
cert
));
byte
[]
signedData
=
baos
.
toByteArray
();
byte
[]
signedData
=
baos
.
toByteArray
();
outputJar
.
write
(
signedData
);
outputJar
.
write
(
signedData
);
// CERT.{EC,RSA} / CERT#.{EC,RSA}
// CERT.{EC,RSA} / CERT#.{EC,RSA}
final
String
keyType
=
publicKey
.
getPublicKey
().
getAlgorithm
();
final
String
keyType
=
cert
.
getPublicKey
().
getAlgorithm
();
je
=
new
JarEntry
(
String
.
format
(
CERT_SIG_NAME
,
keyType
));
je
=
new
JarEntry
(
String
.
format
(
CERT_SIG_NAME
,
keyType
));
je
.
setTime
(
timestamp
);
je
.
setTime
(
timestamp
);
outputJar
.
putNextEntry
(
je
);
outputJar
.
putNextEntry
(
je
);
writeSignatureBlock
(
new
CMSProcessableByteArray
(
signedData
),
writeSignatureBlock
(
new
CMSProcessableByteArray
(
signedData
),
publicKey
,
privateKey
,
outputJar
);
cert
,
privateKey
,
outputJar
);
}
}
}
}
signing/src/main/java/com/topjohnwu/signing/ZipSigner.java
View file @
325d9a0b
...
@@ -4,23 +4,61 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
@@ -4,23 +4,61 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
import
java.io.FileInputStream
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.security.KeyStore
;
import
java.security.KeyStoreException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.PrivateKey
;
import
java.security.Security
;
import
java.security.Security
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
public
class
ZipSigner
{
public
class
ZipSigner
{
p
ublic
static
void
usage
()
{
p
rivate
static
void
usage
()
{
System
.
err
.
println
(
"ZipSigner usage:"
);
System
.
err
.
println
(
"ZipSigner usage:"
);
System
.
err
.
println
(
" zipsigner.jar input.jar output.jar"
);
System
.
err
.
println
(
" zipsigner.jar input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with AOSP test keys"
);
System
.
err
.
println
(
" sign jar with AOSP test keys"
);
System
.
err
.
println
(
" zipsigner.jar x509.pem pk8 input.jar output.jar"
);
System
.
err
.
println
(
" zipsigner.jar x509.pem pk8 input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with certificate / private key pair"
);
System
.
err
.
println
(
" sign jar with certificate / private key pair"
);
System
.
err
.
println
(
" zipsigner.jar
jks keyStorePass keyA
lias keyPass input.jar output.jar"
);
System
.
err
.
println
(
" zipsigner.jar
keyStore keyStorePass a
lias keyPass input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with Java KeyStore"
);
System
.
err
.
println
(
" sign jar with Java KeyStore"
);
System
.
exit
(
2
);
System
.
exit
(
2
);
}
}
private
static
void
sign
(
JarMap
input
,
OutputStream
output
)
throws
Exception
{
sign
(
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
),
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
),
input
,
output
);
}
private
static
void
sign
(
InputStream
certIs
,
InputStream
keyIs
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
X509Certificate
cert
=
CryptoUtils
.
readCertificate
(
certIs
);
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIs
);
SignAPK
.
signAndAdjust
(
cert
,
key
,
input
,
output
);
}
private
static
void
sign
(
String
keyStore
,
String
keyStorePass
,
String
alias
,
String
keyPass
,
JarMap
in
,
OutputStream
out
)
throws
Exception
{
KeyStore
ks
;
try
{
ks
=
KeyStore
.
getInstance
(
"JKS"
);
try
(
InputStream
is
=
new
FileInputStream
(
keyStore
))
{
ks
.
load
(
is
,
keyStorePass
.
toCharArray
());
}
}
catch
(
KeyStoreException
|
IOException
|
CertificateException
|
NoSuchAlgorithmException
e
)
{
ks
=
KeyStore
.
getInstance
(
"PKCS12"
);
try
(
InputStream
is
=
new
FileInputStream
(
keyStore
))
{
ks
.
load
(
is
,
keyStorePass
.
toCharArray
());
}
}
X509Certificate
cert
=
(
X509Certificate
)
ks
.
getCertificate
(
alias
);
PrivateKey
key
=
(
PrivateKey
)
ks
.
getKey
(
alias
,
keyPass
.
toCharArray
());
SignAPK
.
signAndAdjust
(
cert
,
key
,
in
,
out
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
if
(
args
.
length
!=
2
&&
args
.
length
!=
4
&&
args
.
length
!=
6
)
if
(
args
.
length
!=
2
&&
args
.
length
!=
4
&&
args
.
length
!=
6
)
usage
();
usage
();
...
@@ -30,16 +68,14 @@ public class ZipSigner {
...
@@ -30,16 +68,14 @@ public class ZipSigner {
try
(
JarMap
in
=
new
JarMap
(
args
[
args
.
length
-
2
],
false
);
try
(
JarMap
in
=
new
JarMap
(
args
[
args
.
length
-
2
],
false
);
OutputStream
out
=
new
FileOutputStream
(
args
[
args
.
length
-
1
]))
{
OutputStream
out
=
new
FileOutputStream
(
args
[
args
.
length
-
1
]))
{
if
(
args
.
length
==
2
)
{
if
(
args
.
length
==
2
)
{
SignAPK
.
sign
(
in
,
out
);
sign
(
in
,
out
);
}
else
if
(
args
.
length
==
4
)
{
}
else
if
(
args
.
length
==
4
)
{
try
(
InputStream
cert
=
new
FileInputStream
(
args
[
0
]);
try
(
InputStream
cert
=
new
FileInputStream
(
args
[
0
]);
InputStream
key
=
new
FileInputStream
(
args
[
1
]))
{
InputStream
key
=
new
FileInputStream
(
args
[
1
]))
{
SignAPK
.
sign
(
cert
,
key
,
in
,
out
);
sign
(
cert
,
key
,
in
,
out
);
}
}
}
else
if
(
args
.
length
==
6
)
{
}
else
if
(
args
.
length
==
6
)
{
try
(
InputStream
jks
=
new
FileInputStream
(
args
[
0
]))
{
sign
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
in
,
out
);
SignAPK
.
sign
(
jks
,
args
[
1
],
args
[
2
],
args
[
3
],
in
,
out
);
}
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment