1 | // TODO: Android N seems to deprecate SHA1PRNG |
2 | // https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html |
3 | |
4 | static class PKI { |
5 | static String getProvider() { |
6 | return isAndroid() ? /*"AndroidOpenSSL"*/ "BC" : "SUN"; |
7 | } |
8 | |
9 | public static boolean verifySignature(byte[] publicKey, byte[] signature, String file) |
10 | throws InvalidKeyException, NoSuchProviderException, NoSuchAlgorithmException, IOException, SignatureException, InvalidKeySpecException { |
11 | Signature sig = initPublicSignature(publicKey); |
12 | |
13 | FileInputStream datafis = new FileInputStream(file); |
14 | BufferedInputStream bufin = new BufferedInputStream(datafis); |
15 | |
16 | byte[] buffer = new byte[1024]; |
17 | while (bufin.available() != 0) { |
18 | int len = bufin.read(buffer); |
19 | sig.update(buffer, 0, len); |
20 | } |
21 | |
22 | bufin.close(); |
23 | |
24 | return sig.verify(signature); |
25 | } |
26 | |
27 | public static boolean verifySignature(byte[] publicKey, byte[] signature, byte[] data) ctex { |
28 | Signature sig = initPublicSignature(publicKey); |
29 | sig.update(data); |
30 | return sig.verify(signature); |
31 | } |
32 | |
33 | private static Signature initPublicSignature(byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException { |
34 | Signature sig = Signature.getInstance("SHA1withDSA", getProvider()); |
35 | PublicKey pub = KeyFactory.getInstance("DSA", getProvider()).generatePublic(new X509EncodedKeySpec(publicKey)); |
36 | sig.initVerify(pub); |
37 | return sig; |
38 | } |
39 | |
40 | public static byte[] sign(String file, byte[] privateKey) ctex { |
41 | Signature dsa = initSignature(privateKey); |
42 | |
43 | FileInputStream fis = new FileInputStream(file); |
44 | BufferedInputStream bufin = new BufferedInputStream(fis); |
45 | byte[] buffer = new byte[1024]; |
46 | int len; |
47 | while ((len = bufin.read(buffer)) >= 0) |
48 | dsa.update(buffer, 0, len); |
49 | bufin.close(); |
50 | |
51 | return dsa.sign(); |
52 | } |
53 | |
54 | public static byte[] sign(byte[] data, byte[] privateKey) ctex { |
55 | Signature dsa = initSignature(privateKey); |
56 | dsa.update(data); |
57 | return dsa.sign(); |
58 | } |
59 | |
60 | private static Signature initSignature(byte[] privateKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException { |
61 | Signature dsa = Signature.getInstance("SHA1withDSA", getProvider()); |
62 | //X509EncodedKeySpec keySpec = new X509EncodedKeySpec(privateKey); |
63 | EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); |
64 | PrivateKey priv = KeyFactory.getInstance("DSA", getProvider()).generatePrivate(keySpec); |
65 | dsa.initSign(priv); |
66 | return dsa; |
67 | } |
68 | |
69 | public static KeyPair makeKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException { |
70 | KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", getProvider()); |
71 | // OLD SecureRandom random = SecureRandom.getInstance("SHA1PRNG", getProvider()); |
72 | // should work on Android? |
73 | SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); |
74 | |
75 | keyGen.initialize(1024, random); |
76 | return keyGen.generateKeyPair(); |
77 | } |
78 | |
79 | // Standard key pair is for the MACHINE (not the user) |
80 | public static boolean makeStandardKeyPairIfNecessary() ctex { |
81 | File publicKeyPath = getStandardPublicKeyPath(); |
82 | File privateKeyPath = getStandardPrivateKeyPath(); |
83 | if (!publicKeyPath.exists() || !privateKeyPath.exists()) { |
84 | print("PKI: Making standard key pair"); |
85 | KeyPair keyPair = makeKeyPair(); |
86 | byte[] privateKey = keyPair.getPrivate().getEncoded(); |
87 | print("PKI: Private key hex (debug) - " + bytesToHex(privateKey)); |
88 | saveTextFile(privateKeyPath, privateKeyToString(privateKey)); |
89 | String publicKey = publicKeyToString(keyPair.getPublic()); |
90 | saveTextFile(publicKeyPath, publicKey); |
91 | print("PKI: Standard key pair made!"); |
92 | print(); |
93 | printInfo(); |
94 | return true; |
95 | } |
96 | return false; |
97 | } |
98 | |
99 | static void printInfo() { |
100 | print("PKI: Machine's public key: " + publicKeyToString(getStandardPublicKey())); |
101 | print("PKI: Machine's private key in: " + getStandardPrivateKeyPath()); |
102 | print("PKI: Machine's public key also in: " + getStandardPublicKeyPath()); |
103 | print("PKI: User's public key: " + publicKeyToString(userPublicKey())); |
104 | print("PKI: User's private key in: " + userPrivateKeyPath()); |
105 | print("PKI: User's public key also in: " + userPublicKeyPath()); |
106 | } |
107 | |
108 | public static File getStandardPrivateKeyPath() { |
109 | return new File(getSecretProgramDir("#1001547"), "Computer-Private-Key"); |
110 | } |
111 | |
112 | public static File userPublicKeyPath() { |
113 | return new File(getProgramDir("#1001547"), "User-Public-Key"); |
114 | } |
115 | |
116 | public static File userPrivateKeyPath() { |
117 | return new File(getSecretProgramDir("#1001547"), "User-Private-Key"); |
118 | } |
119 | |
120 | public static File getStandardPublicKeyPath() { |
121 | return new File(getProgramDir("#1001547"), "Computer-Public-Key"); |
122 | } |
123 | |
124 | public static byte[] getStandardPrivateKey() { |
125 | makeStandardKeyPairIfNecessary(); |
126 | return privateKeyFromString(loadTextFile(getStandardPrivateKeyPath())); |
127 | } |
128 | |
129 | public static byte[] getStandardPublicKey() { |
130 | makeStandardKeyPairIfNecessary(); |
131 | return publicKeyFromString(loadTextFile(getStandardPublicKeyPath())); |
132 | } |
133 | |
134 | public static byte[] userPrivateKey() { |
135 | makeUserKeyPairIfNecessary(); |
136 | return privateKeyFromString(loadTextFile(userPrivateKeyPath())); |
137 | } |
138 | |
139 | public static byte[] userPublicKey() { |
140 | makeUserKeyPairIfNecessary(); |
141 | return publicKeyFromString(loadTextFile(userPublicKeyPath())); |
142 | } |
143 | |
144 | private static String publicKeyToString(PublicKey publicKey) { |
145 | return publicKeyToString(publicKey.getEncoded()); |
146 | } |
147 | |
148 | public static String privateKeyToString(PrivateKey privateKey) { |
149 | return privateKeyToString(privateKey.getEncoded()); |
150 | } |
151 | |
152 | public static byte[] publicKeyFromString(String key) { |
153 | return base64decode(dropPrefixMandatory("publickey:", trim(key))); |
154 | } |
155 | |
156 | public static byte[] privateKeyFromString(String key) { |
157 | return base64decode(dropPrefixMandatory("privatekey:", trim(key))); |
158 | } |
159 | |
160 | public static byte[] signatureFromString(String key) { |
161 | return base64decode(key); |
162 | } |
163 | |
164 | public static byte[] dataFromString(String text) { |
165 | return toUtf8(text); |
166 | } |
167 | |
168 | public static String signatureToString(byte[] signature) { |
169 | return base64encode(signature); |
170 | } |
171 | |
172 | public static String publicKeyToString(byte[] key) { |
173 | return "publickey:" + base64encode(key); |
174 | } |
175 | |
176 | public static String privateKeyToString(byte[] key) { |
177 | return "privatekey:" + base64encode(key); |
178 | } |
179 | |
180 | static boolean makeUserKeyPairIfNecessary() ctex { |
181 | File publicKeyPath = userPublicKeyPath(); |
182 | File privateKeyPath = userPrivateKeyPath(); |
183 | if (!publicKeyPath.exists() || !privateKeyPath.exists()) { |
184 | print("PKI: Making user key pair"); |
185 | KeyPair keyPair = makeKeyPair(); |
186 | byte[] privateKey = keyPair.getPrivate().getEncoded(); |
187 | print("PKI: Private key hex (debug) - " + bytesToHex(privateKey)); |
188 | saveTextFile(privateKeyPath, privateKeyToString(privateKey)); |
189 | String publicKey = publicKeyToString(keyPair.getPublic()); |
190 | saveTextFile(publicKeyPath, publicKey); |
191 | print("PKI: User key pair made!"); |
192 | print(); |
193 | printInfo(); |
194 | return true; |
195 | } |
196 | return false; |
197 | } |
198 | } |
download show line numbers debug dex old transpilations
Travelled to 17 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, sawdedvomwva, tslmcundralx, tvejysmllsmz, vouqrxazstgt, whxojlpjdney, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1001548 |
Snippet name: | PKI (Public Key Infrastructure, include) |
Eternal ID of this version: | #1001548/6 |
Text MD5: | 10b11f88e89db899a4d9238fd9bda085 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-07-17 13:29:16 |
Source code size: | 7385 bytes / 198 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 709 / 1860 |
Version history: | 5 change(s) |
Referenced in: | [show references] |