Android KeyGenParameterSpec.Builder ignoring setCertificateNotBefore and setCertificateNotAfter when not in Secure Hadware

ε祈祈猫儿з 提交于 2020-06-01 05:02:41

问题


I've created the following method that creates a KeyPair and logs the Certificate details:

@RequiresApi(api = Build.VERSION_CODES.N)
public void createRSAKeyPairtWithChallenge(final String alias, final String attestationChallenge) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyStoreException, CertificateException, IOException {
    Calendar start = Calendar.getInstance();
    Calendar end = new GregorianCalendar(2025,03,24);
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
    keyPairGenerator.initialize(
            new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_DECRYPT)
                    .setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(1024, RSAKeyGenParameterSpec.F4))
                    .setCertificateNotBefore(start.getTime())
                    .setCertificateNotAfter(end.getTime())
                    .setAttestationChallenge(attestationChallenge.getBytes())
                    .build());
    keyPairGenerator.generateKeyPair();

    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

    keyStore.load(null);

    Certificate cert = keyStore.getCertificate(alias);
    Log.d(TAG,cert.toString());
}

When I execute in a device with a Secure Hardware (TEE) it creates the cert as expected, but when I execute in a device whithout TEE or in emulator it logs the following:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Android Keymaster
        Validity
            Not Before: Jan  1 00:00:00 1970 GMT
            Not After : Dec 31 23:59:59 1969 GMT
        Subject: CN=A Keymaster Key
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:8c:d1:bf:0e:22:ea:62:ad:e6:6d:9c:41:5c:d6:
                    f1:a1:17:6a:e4:e2:12:f7:45:21:70:ef:c0:c5:d7:
                    18:41:35:9c:42:c4:c6:11:48:0a:2d:97:a4:2a:54:
                    a0:7f:01:61:22:2e:2b:df:76:99:6c:e1:84:b9:ad:
                    f5:97:65:a7:f9:2b:bf:97:32:f8:b1:f2:06:3b:2b:
                    67:cb:ff:28:e4:1b:74:01:47:e9:91:0b:41:ec:17:
                    fe:4a:b4:3a:f5:0c:db:9b:fa:f3:c1:ef:e0:f5:bf:
                    e8:37:f9:b2:23:86:96:c4:50:5d:64:ba:b7:1b:61:
                    3f:65:54:2f:39:9b:d4:98:91
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: 
                Key Encipherment, Data Encipherment
            1.3.6.1.4.1.11129.2.1.17: 
                0b...
.....
....test-cert-challenge..0..=........+L0...1.................H........w.....>......?...
            X509v3 Authority Key Identifier: 
                keyid:D4:0C:10:1B:F8:CD:63:B9:F7:39:52:B5:0E:13:5C:A6:D7:99:93:86

    Signature Algorithm: sha256WithRSAEncryption
         40:79:42:eb:a2:22:e7:e5:95:8f:98:c8:de:35:80:b5:7b:fe:
         20:19:00:39:5b:59:3a:49:e0:10:06:c4:c4:a1:3e:52:69:7a:
         09:7b:39:67:28:3c:6a:94:96:9e:86:72:58:51:d9:96:0e:a8:
         1a:d9:d9:bf:24:6f:79:58:28:a5:1a:7d:14:ae:32:04:9c:e4:
         bf:1b:80:d3:4a:85:c2:e0:ab:b3:2c:b9:10:b2:ad:b2:36:00:
         68:eb:1b:52:85:b6:d0:0c:93:d5:bc:a5:35:1a:0c:02:a6:af:
         86:ee:2c:92:ef:25:5e:56:99:77:4f:72:8a:80:1a:54:33:1f:
         78:98 

As you can see the dates in Not Before and Not After are not as expected.

Does anybody know what could be the reason?


回答1:


Hy, I tried you're code locally and had the same results as you already told. I also tried to manipulate the start and end dates to get:

java.lang.IllegalArgumentException: certificateNotAfter < certificateNotBefore
        at android.security.keystore.KeyGenParameterSpec.<init>(KeyGenParameterSpec.java:328)
        at android.security.keystore.KeyGenParameterSpec$Builder.build(KeyGenParameterSpec.java:1340)
        at org.chickenhook.binderfuzzy.MainActivity.createRSAKeyPairtWithChallenge(MainActivity.kt:47)
        at org.chickenhook.binderfuzzy.MainActivity.onCreate(MainActivity.kt:28)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

This just tells us that you're params are set correctly and correctly interpreted by the Android OS also on non TEE devices.

Also I checked the Android documentation and found out that not all Keystore implementations may care about start and end date in a "secure manner" (https://developer.android.com/training/articles/keystore).

"Temporal validity interval authorizations are unlikely to be enforced by the secure hardware because it normally doesn't have an independent secure real-time clock. "

This doesn't answer you're question deterministic but tells that not all environments care about time validity because it's just not "secure". So it's better to give no time validity in order to tell there is no security for it rather than to meme validation time that doesn't really help.

Please consider that 23:59:59 1969 etc. means time_t notBefore(time_t)-1 and the 1970 means time_t notAfter=(time_t)0. So I beleve they disabled the validity but it's required that notebefore < notAfter.

However this not a deterministic answer, still searching for documentation explaining this issue in detail :(.



来源:https://stackoverflow.com/questions/61901095/android-keygenparameterspec-builder-ignoring-setcertificatenotbefore-and-setcert

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!