|
26 | 26 | import android.content.Context; |
27 | 27 | import android.os.Build; |
28 | 28 | import android.security.KeyPairGeneratorSpec; |
| 29 | +import android.security.keystore.KeyGenParameterSpec; |
| 30 | +import android.security.keystore.KeyProperties; |
29 | 31 |
|
30 | 32 | import androidx.annotation.RequiresApi; |
31 | 33 |
|
|
44 | 46 | import java.security.KeyStore; |
45 | 47 | import java.security.spec.AlgorithmParameterSpec; |
46 | 48 | import java.util.Calendar; |
| 49 | +import java.util.Date; |
47 | 50 | import java.util.Locale; |
| 51 | +import java.util.concurrent.TimeUnit; |
48 | 52 |
|
49 | 53 | import javax.crypto.SecretKey; |
50 | 54 | import javax.security.auth.x500.X500Principal; |
@@ -273,25 +277,43 @@ public void deleteSecretKeyFromStorage() throws ClientException { |
273 | 277 | * @param context an Android {@link Context} object. |
274 | 278 | * @return a {@link AlgorithmParameterSpec} for the keystore key (that we'll use to wrap the secret key). |
275 | 279 | */ |
276 | | - @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) |
277 | | - private static AlgorithmParameterSpec getSpecForKeyStoreKey(@NonNull final Context context, |
278 | | - @NonNull final String alias) { |
| 280 | +// @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) |
| 281 | +// private static AlgorithmParameterSpec getLegacySpecForKeyStoreKey(@NonNull final Context context, |
| 282 | +// @NonNull final String alias) { |
| 283 | +// // Generate a self-signed cert. |
| 284 | +// final String certInfo = String.format(Locale.ROOT, "CN=%s, OU=%s", |
| 285 | +// alias, |
| 286 | +// context.getPackageName()); |
| 287 | +// |
| 288 | +// final Calendar start = Calendar.getInstance(); |
| 289 | +// final Calendar end = Calendar.getInstance(); |
| 290 | +// final int certValidYears = 100; |
| 291 | +// end.add(Calendar.YEAR, certValidYears); |
| 292 | +// |
| 293 | +// return new KeyPairGeneratorSpec.Builder(context) |
| 294 | +// .setAlias(alias) |
| 295 | +// .setSubject(new X500Principal(certInfo)) |
| 296 | +// .setSerialNumber(BigInteger.ONE) |
| 297 | +// .setStartDate(start.getTime()) |
| 298 | +// .setEndDate(end.getTime()) |
| 299 | +// .build(); |
| 300 | +// } |
| 301 | + |
| 302 | + |
| 303 | + private static AlgorithmParameterSpec getSpecForKeyStoreKey(@NonNull final Context context, @NonNull final String alias) { |
279 | 304 | // Generate a self-signed cert. |
280 | 305 | final String certInfo = String.format(Locale.ROOT, "CN=%s, OU=%s", |
281 | 306 | alias, |
282 | 307 | context.getPackageName()); |
283 | | - |
284 | | - final Calendar start = Calendar.getInstance(); |
285 | | - final Calendar end = Calendar.getInstance(); |
286 | 308 | final int certValidYears = 100; |
287 | | - end.add(Calendar.YEAR, certValidYears); |
288 | | - |
289 | | - return new KeyPairGeneratorSpec.Builder(context) |
290 | | - .setAlias(alias) |
291 | | - .setSubject(new X500Principal(certInfo)) |
292 | | - .setSerialNumber(BigInteger.ONE) |
293 | | - .setStartDate(start.getTime()) |
294 | | - .setEndDate(end.getTime()) |
| 309 | + return new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_WRAP_KEY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) |
| 310 | + .setCertificateSubject(new X500Principal(certInfo)) |
| 311 | + .setCertificateSerialNumber(BigInteger.ONE) |
| 312 | + .setCertificateNotBefore(new Date()) |
| 313 | + .setCertificateNotAfter(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(365 * certValidYears))) |
| 314 | + .setKeySize(2048) |
| 315 | + .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) |
| 316 | + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) |
295 | 317 | .build(); |
296 | 318 | } |
297 | 319 |
|
|
0 commit comments