Home | History | Annotate | Download | only in articles
      1 page.title=Android Keystore System
      2 @jd:body
      3 
      4 <div id="tb-wrapper">
      5 <div id="tb">
      6     <h2>In this document</h2>
      7     <ol>
      8       <li><a href="#SecurityFeatures">Security Features</a></li>
      9       <li><a href="#WhichShouldIUse">Choosing Between a Keychain or the Android Keystore Provider</a></li>
     10       <li><a href="#UsingAndroidKeyStore">Using Android Keystore Provider</a>
     11       <ol>
     12         <li><a href="#GeneratingANewPrivateKey">Generating a New Private Key</a></li>
     13         <li><a href="#WorkingWithKeyStoreEntries">Working with Keystore Entries</a></li>
     14         <li><a href="#ListingEntries">Listing Entries</a></li>
     15         <li><a href="#SigningAndVerifyingData">Signing and Verifying Data</a></li>
     16       </ol>
     17       </li>
     18       <li><a href="#SupportedAlgorithms">Supported Algorithms</a></li>
     19     </ol>
     20 
     21     <h2>Blog articles</h2>
     22     <ol>
     23       <li><a
     24         href="http://android-developers.blogspot.com/2012/03/unifying-key-store-access-in-ics.html">
     25           <h4>Unifying Key Store Access in ICS</h4>
     26       </a></li>
     27     </ol>
     28   </div>
     29 </div>
     30 
     31 <style type="text/css">
     32   tr.deprecated {
     33     background-color: #ccc;
     34     color: #999;
     35     font-style: italic;
     36   }
     37 </style>
     38 
     39 <p>The Android Keystore system lets you store cryptographic keys in a container
     40   to make it more difficult to extract from the device. Once keys are in the
     41   keystore, they can be used for cryptographic operations with the key material
     42   remaining non-exportable. Moreover, it offers facilities to restrict when and
     43   how keys can be used, such as requiring user authentication for key use or
     44   restricting keys to be used only in certain cryptographic modes. See
     45   <a href="#SecurityFeatures">Security Features</a> section for more information.</p>
     46 
     47 <p>The Keystore system is used by the {@link
     48   android.security.KeyChain} API as well as the Android
     49   Keystore provider feature that was introduced in Android 4.3
     50   (API level 18). This document goes over when and how to use the
     51   Android Keystore provider.</p>
     52 
     53 
     54 <h2 id="SecurityFeatures">Security Features</h2>
     55 
     56 Android Keystore system protects key material from unauthorized use. Firstly, Android Keystore
     57 mitigates unauthorized use of key material outside of the Android device by preventing extraction of
     58 the key material from application processes and from the Android device as a whole. Secondly,
     59 Android KeyStore mitigates unauthorized use of key material on the Android device by making apps
     60 specify authorized uses of their keys and then enforcing these restrictions outside of the apps'
     61 processes.
     62 
     63 <h3 id="ExtractionPrevention">Extraction Prevention</h3>
     64 
     65 Key material of Android Keystore keys is protected from extraction using two security measures:
     66 <ul>
     67 <li>Key material never enters the application process. When an application performs cryptographic
     68   operations using an Android Keystore key, behind the scenes plaintext, ciphertext, and messages to
     69   be signed or verified are fed to a system process which carries out the cryptographic operations.
     70   If the app's process is compromised, the attacker may be able to use the app's keys but will not
     71   be able to extract their key material (for example, to be used outside of the Android device).
     72   </li>
     73 <li>Key material may be bound to the secure hardware (e.g., Trusted Execution Environment (TEE),
     74   Secure Element (SE)) of the Android device. When this feature is enabled for a key, its key
     75   material is never exposed outside of secure hardware. If the Android OS is compromised or an
     76   attacker can read the device's internal storage, the attacker may be able to use any app's Android
     77   Keystore keys on the Android device, but not extract them from the device. This feature is enabled
     78   only if the device's secure hardware supports the particular combination of key algorithm, block
     79   modes, padding schemes, and digests with which the key is authorized to be used. To check whether
     80   the feature is enabled for a key, obtain a {@link android.security.keystore.KeyInfo} for the key
     81   and inspect the return value of
     82   {@link android.security.keystore.KeyInfo#isInsideSecureHardware() KeyInfo.isInsideSecurityHardware()}.
     83   </li>
     84 </ul>
     85 
     86 <h3 id="KeyUseAuthorizations">Key Use Authorizations</h3>
     87 
     88 To mitigate unauthorized use of keys on the Android device, Android Keystore lets apps specify
     89 authorized uses of their keys when generating or importing the keys. Once a key is generated or
     90 imported, its authorizations can not be changed. Authorizations are then enforced by the Android
     91 Keystore whenever the key is used. This is an advanced security feature which is generally useful
     92 only if your requirements are that a compromise of your application process after key
     93 generation/import (but not before or during) cannot lead to unauthorized uses of the key.
     94 
     95 <p>Supported key use authorizations fall into the following categories:
     96 <ul>
     97 <li><em>cryptography</em>: authorized key algorithm, operations or purposes (encrypt, decrypt, sign,
     98   verify), padding schemes, block modes, digests with which the key can be used;</li>
     99 <li><em>temporal validity interval</em>: interval of time during which the key is authorized for
    100   use;</li>
    101 <li><em>user authentication</em>: the key can only be used if the user has been authenticated
    102   recently enough. See <a href="#UserAuthentication">Requiring User Authentication For Key Use</a>.
    103   </li>
    104 </ul>
    105 
    106 <p>As an additional security measure, for keys whose key material is inside secure hardware (see
    107   {@link android.security.keystore.KeyInfo#isInsideSecureHardware() KeyInfo.isInsideSecurityHardware()})
    108   some key use authorizations may be enforced by secure hardware, depending on the Android device.
    109   Cryptographic and user authentication authorizations are likely to be enforced by secure hardware.
    110   Temporal validity interval authorizations are unlikely to be enforced by the secure hardware
    111   because it normally does not have an independent secure real-time clock.
    112 
    113 <p>Whether a key's user authentication authorization is enforced by the secure hardware can be
    114   queried using
    115   {@link android.security.keystore.KeyInfo#isUserAuthenticationRequirementEnforcedBySecureHardware() KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()}.
    116 
    117 <h2 id="WhichShouldIUse">Choosing Between a Keychain or the
    118 Android Keystore Provider</h2>
    119 
    120 <p>Use the {@link android.security.KeyChain} API when you want
    121   system-wide credentials. When an app requests the use of any credential
    122   through the {@link android.security.KeyChain} API, users get to
    123   choose, through a system-provided UI, which of the installed credentials
    124   an app can access. This allows several apps to use the
    125   same set of credentials with user consent.</p>
    126 
    127 <p>Use the Android Keystore provider to let an individual app store its own
    128   credentials that only the app itself can access.
    129   This provides a way for apps to manage credentials that are usable
    130   only by itself while providing the same security benefits that the
    131   {@link android.security.KeyChain} API provides for system-wide
    132   credentials. This method requires no user interaction to select the credentials.</p>
    133 
    134 <h2 id="UsingAndroidKeyStore">Using Android Keystore Provider</h2>
    135 
    136 <p>
    137 To use this feature, you use the standard {@link java.security.KeyStore}
    138 and {@link java.security.KeyPairGenerator} or
    139 {@link javax.crypto.KeyGenerator} classes along with the
    140 {@code AndroidKeyStore} provider introduced in Android 4.3 (API level 18).</p>
    141 
    142 <p>{@code AndroidKeyStore} is registered as a {@link
    143   java.security.KeyStore} type for use with the {@link
    144   java.security.KeyStore#getInstance(String) KeyStore.getInstance(type)}
    145   method and as a provider for use with the {@link
    146   java.security.KeyPairGenerator#getInstance(String, String)
    147   KeyPairGenerator.getInstance(algorithm, provider)} and {@link
    148   javax.crypto.KeyGenerator#getInstance(String, String)
    149   KeyGenerator.getInstance(algorithm, provider)} methods.</p>
    150 
    151 <h3 id="GeneratingANewPrivateKey">Generating a New Private Key</h3>
    152 
    153 <p>Generating a new {@link java.security.PrivateKey} requires that
    154   you also specify the initial X.509 attributes that the self-signed
    155   certificate will have. You can use
    156   {@link java.security.KeyStore#setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[]) KeyStore.setKeyEntry}
    157   to replace the certificate at a later time with a certificate signed
    158   by a Certificate Authority (CA).</p>
    159 
    160 <p>To generate the key, use a {@link java.security.KeyPairGenerator}
    161   with {@link android.security.KeyPairGeneratorSpec}:</p>
    162 
    163 {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java generate}
    164 
    165 <h3 id="GeneratingANewSecretKey">Generating a New Secret Key</h3>
    166 
    167 <p>To generate the key, use a {@link javax.crypto.KeyGenerator} with
    168   {@link android.security.keystore.KeyGenParameterSpec}.
    169 
    170 <h3 id="WorkingWithKeyStoreEntries">Working with Keystore Entries</h3>
    171 
    172 <p>Using the {@code AndroidKeyStore} provider takes place through
    173   all the standard {@link java.security.KeyStore} APIs.</p>
    174 
    175 <h4 id="ListingEntries">Listing Entries</h4>
    176 
    177 <p>List entries in the keystore by calling the {@link
    178   java.security.KeyStore#aliases()} method:</p>
    179 
    180 {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java list}
    181 
    182 <h4 id="SigningAndVerifyingData">Signing and Verifying Data</h4>
    183 
    184 <p>Sign data by fetching the {@link
    185   java.security.KeyStore.Entry} from the keystore and using the
    186   {@link java.security.Signature} APIs, such as {@link
    187   java.security.Signature#sign()}:</p>
    188 
    189 {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java sign}
    190 
    191 <p>Similarly, verify data with the {@link java.security.Signature#verify(byte[])} method:</p>
    192 
    193 {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java verify}
    194 
    195 <h3 id="UserAuthentication">Requiring User Authentication For Key Use</h3>
    196 
    197 <p>When generating or importing a key into the {@code AndroidKeyStore} you can specify that the key
    198 is only authorized to be used if the user has been authenticated. The user is authenticated using a
    199 subset of their secure lock screen credentials (pattern/PIN/password, fingerprint).
    200 
    201 <p>This is an advanced security feature which is generally useful only if your requirements are that
    202 a compromise of your application process after key generation/import (but not before or during)
    203 cannot bypass the requirement for the user to be authenticated to use the key.
    204 
    205 <p>When a key is authorized to be used only if the user has been authenticated, it is configured to
    206 operate in one of the two modes:
    207 <ul>
    208 <li>User authentication authorizes the use of keys for a duration of time. All keys in this mode are
    209   authorized for use as soon as the user unlocks the secure lock screen or confirms their secure
    210   lock screen credential using the
    211   {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
    212   flow. The duration for which the authorization remains valid is specific to each key, as specified
    213   using {@code setUserAuthenticationValidityDurationSeconds} during key generation or import. Such
    214   keys can only be generated or imported if the secure lock screen is enabled (see
    215   {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}). These keys
    216   become permanently invalidated once the secure lock screen is disabled (reconfigured to None,
    217   Swipe or other mode which does not authenticate the user) or forcibly reset (e.g. by a Device
    218   Administrator).</li>
    219 <li>User authentication authorizes a specific cryptographic operation associated with one key. In
    220   this mode, each operation involving such a key must be individually authorized by the user.
    221   Currently, the only means of such authorization is fingerprint authentication:
    222   {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
    223   Such keys can only be generated or imported if at least one fingerprint is enrolled (see
    224   {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
    225   These keys become permanently invalidated once a new fingerprint is enrolled or all fingerprints
    226   are unenrolled.</li>
    227 </ul>
    228 
    229 <h2 id="SupportedAlgorithms">Supported Algorithms</h2>
    230 
    231 <ul>
    232   <li><a href="#SupportedCiphers">{@code Cipher}</a></li>
    233   <li><a href="#SupportedKeyGenerators">{@code KeyGenerator}</a></li>
    234   <li><a href="#SupportedKeyFactories">{@code KeyFactory}</a></li>
    235   <li><a href="#SupportedKeyPairGenerators">{@code KeyPairGenerator}</a></li>
    236   <li><a href="#SupportedMacs">{@code Mac}</a></li>
    237   <li><a href="#SupportedSignatures">{@code Signature}</a></li>
    238   <li><a href="#SupportedSecretKeyFactories">{@code SecretKeyFactory}</a></li>
    239 </ul>
    240 
    241 <h3 id="SupportedCiphers">Cipher</h3>
    242 <table>
    243   <thead>
    244     <tr>
    245       <th>Algorithm</th>
    246       <th>Supported (API Levels)</th>
    247       <th>Notes</th>
    248     </tr>
    249   </thead>
    250   <tbody>
    251     <tr>
    252       <td>AES/CBC/NoPadding</td>
    253       <td>23+</td>
    254       <td></td>
    255     </tr>
    256     <tr>
    257       <td>AES/CBC/PKCS7Padding</td>
    258       <td>23+</td>
    259       <td></td>
    260     </tr>
    261     <tr>
    262       <td>AES/CTR/NoPadding</td>
    263       <td>23+</td>
    264       <td></td>
    265     </tr>
    266     <tr>
    267       <td>AES/ECB/NoPadding</td>
    268       <td>23+</td>
    269       <td></td>
    270     </tr>
    271     <tr>
    272       <td>AES/ECB/PKCS7Padding</td>
    273       <td>23+</td>
    274       <td></td>
    275     </tr>
    276     <tr>
    277       <td>AES/GCM/NoPadding</td>
    278       <td>23+</td>
    279       <td>Only 12-byte long IVs supported.</td>
    280     </tr>
    281     <tr>
    282       <td>RSA/ECB/NoPadding</td>
    283       <td>18+</td>
    284       <td></td>
    285     </tr>
    286     <tr>
    287       <td>RSA/ECB/PKCS1Padding</td>
    288       <td>18+</td>
    289       <td></td>
    290     </tr>
    291     <tr>
    292       <td>RSA/ECB/OAEPWithSHA-1AndMGF1Padding</td>
    293       <td>23+</td>
    294       <td></td>
    295     </tr>
    296     <tr>
    297       <td>RSA/ECB/OAEPWithSHA-224AndMGF1Padding</td>
    298       <td>23+</td>
    299       <td></td>
    300     </tr>
    301     <tr>
    302       <td>RSA/ECB/OAEPWithSHA-256AndMGF1Padding</td>
    303       <td>23+</td>
    304       <td></td>
    305     </tr>
    306     <tr>
    307       <td>RSA/ECB/OAEPWithSHA-384AndMGF1Padding</td>
    308       <td>23+</td>
    309       <td></td>
    310     </tr>
    311     <tr>
    312       <td>RSA/ECB/OAEPWithSHA-512AndMGF1Padding</td>
    313       <td>23+</td>
    314       <td></td>
    315     </tr>
    316     <tr>
    317       <td>RSA/ECB/OAEPPadding</td>
    318       <td>23+</td>
    319       <td></td>
    320     </tr>
    321   </tbody>
    322 </table>
    323 
    324 <h3 id="SupportedKeyGenerators">KeyGenerator</h3>
    325 <table>
    326   <thead>
    327     <tr>
    328       <th>Algorithm</th>
    329       <th>Supported (API Levels)</th>
    330       <th>Notes</th>
    331     </tr>
    332   </thead>
    333   <tbody>
    334     <tr>
    335       <td>AES</td>
    336       <td>23+</td>
    337       <td>Supported sizes: 128, 192, 256</td>
    338     </tr>
    339     <tr>
    340       <td>HmacSHA1</td>
    341       <td>23+</td>
    342       <td>
    343         <ul>
    344           <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li>
    345           <li>Default size: 160</li>
    346         <ul>
    347       </td>
    348     </tr>
    349     <tr>
    350       <td>HmacSHA224</td>
    351       <td>23+</td>
    352       <td>
    353         <ul>
    354           <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li>
    355           <li>Default size: 224</li>
    356         <ul>
    357       </td>
    358     </tr>
    359     <tr>
    360       <td>HmacSHA256</td>
    361       <td>23+</td>
    362       <td>
    363         <ul>
    364           <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li>
    365           <li>Default size: 256</li>
    366         <ul>
    367       </td>
    368     </tr>
    369     <tr>
    370       <td>HmacSHA384</td>
    371       <td>23+</td>
    372       <td>
    373         <ul>
    374           <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li>
    375           <li>Default size: 384</li>
    376         <ul>
    377       </td>
    378     </tr>
    379     <tr>
    380       <td>HmacSHA512</td>
    381       <td>23+</td>
    382       <td>
    383         <ul>
    384           <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li>
    385           <li>Default size: 512</li>
    386         <ul>
    387       </td>
    388     </tr>
    389   </tbody>
    390 </table>
    391 
    392 <h3 id="SupportedKeyFactories">KeyFactory</h3>
    393 <table>
    394   <thead>
    395     <tr>
    396       <th>Algorithm</th>
    397       <th>Supported (API Levels)</th>
    398       <th>Notes</th>
    399     </tr>
    400   </thead>
    401   <tbody>
    402     <tr>
    403       <td>EC</td>
    404       <td>23+</td>
    405       <td>Supported key specs: {@link android.security.keystore.KeyInfo} (private key only),
    406         {@link java.security.spec.ECPublicKeySpec} (public key only),
    407         {@link java.security.spec.X509EncodedKeySpec} (public key only)
    408       </td>
    409     </tr>
    410     <tr>
    411       <td>RSA</td>
    412       <td>23+</td>
    413       <td>Supported key specs: {@link android.security.keystore.KeyInfo} (private key only),
    414         {@link java.security.spec.RSAPublicKeySpec} (public key only),
    415         {@link java.security.spec.X509EncodedKeySpec} (public key only)
    416       </td>
    417     </tr>
    418   </tbody>
    419 </table>
    420 
    421 <h3 id="SupportedKeyStoreKeys">KeyStore</h3>
    422 KeyStore supports the same key types as
    423 <a href="#SupportedKeyPairGenerators">{@code KeyPairGenerator}</a> and
    424 <a href="#SupportedKeyGenerators">{@code KeyGenerator}</a>.
    425 
    426 <h3 id="SupportedKeyPairGenerators">KeyPairGenerator</h3>
    427 <table>
    428   <thead>
    429     <tr>
    430       <th>Algorithm</th>
    431       <th>Supported (API Levels)</th>
    432       <th>Notes</th>
    433     </tr>
    434   </thead>
    435   <tbody>
    436     <tr class="deprecated">
    437       <td>DSA</td>
    438       <td>19&ndash;22</td>
    439       <td></td>
    440     </tr>
    441     <tr>
    442       <td>EC</td>
    443       <td>23+</td>
    444       <td>
    445         <ul>
    446           <li>Supported sizes: 224, 256, 384, 521</li>
    447           <li>Supported named curves: P-224 (secp224r1), P-256 (aka secp256r1 and prime256v1), P-384
    448             (aka secp384r1), P-521 (aka secp521r1)</li>
    449         </ul>
    450 
    451         <p>Prior to API Level 23, EC keys can be generated using KeyPairGenerator of algorithm "RSA"
    452         initialized {@link android.security.KeyPairGeneratorSpec} whose key type is set to "EC"
    453         using {@link android.security.KeyPairGeneratorSpec.Builder#setKeyType(String)}. EC curve
    454         name cannot be specified using this method -- a NIST P-curve is automatically chosen based
    455         on the requested key size.
    456       </td>
    457     </tr>
    458     <tr>
    459       <td>RSA</td>
    460       <td>18+</td>
    461       <td>
    462         <ul>
    463           <li>Supported sizes: 512, 768, 1024, 2048, 3072, 4096</li>
    464           <li>Supported public exponents: 3, 65537</li>
    465           <li>Default public exponent: 65537</li>
    466         </ul>
    467       </td>
    468     </tr>
    469   </tbody>
    470 </table>
    471 
    472 <h3 id="SupportedMacs">Mac</h3>
    473 <table>
    474   <thead>
    475     <tr>
    476       <th>Algorithm</th>
    477       <th>Supported (API Levels)</th>
    478       <th>Notes</th>
    479     </tr>
    480   </thead>
    481   <tbody>
    482     <tr>
    483       <td>HmacSHA1</td>
    484       <td>23+</td>
    485       <td></td>
    486     </tr>
    487     <tr>
    488       <td>HmacSHA224</td>
    489       <td>23+</td>
    490       <td></td>
    491     </tr>
    492     <tr>
    493       <td>HmacSHA256</td>
    494       <td>23+</td>
    495       <td></td>
    496     </tr>
    497     <tr>
    498       <td>HmacSHA384</td>
    499       <td>23+</td>
    500       <td></td>
    501     </tr>
    502     <tr>
    503       <td>HmacSHA512</td>
    504       <td>23+</td>
    505       <td></td>
    506     </tr>
    507   </tbody>
    508 </table>
    509 
    510 <h3 id="SupportedSignatures">Signature</h3>
    511 <table>
    512   <thead>
    513     <tr>
    514       <th>Algorithm</th>
    515       <th>Supported (API Levels)</th>
    516       <th>Notes</th>
    517     </tr>
    518   </thead>
    519   <tbody>
    520     <tr>
    521       <td>MD5withRSA</td>
    522       <td>18+</td>
    523       <td></td>
    524     </tr>
    525     <tr>
    526       <td>NONEwithECDSA</td>
    527       <td>23+</td>
    528       <td></td>
    529     </tr>
    530     <tr>
    531       <td>NONEwithRSA</td>
    532       <td>18+</td>
    533       <td></td>
    534     </tr>
    535     <tr class="deprecated">
    536       <td>SHA1withDSA</td>
    537       <td>19&ndash;22</td>
    538       <td></td>
    539     </tr>
    540     <tr>
    541       <td>SHA1withECDSA</td>
    542       <td>19+</td>
    543       <td></td>
    544     </tr>
    545     <tr>
    546       <td>SHA1withRSA</td>
    547       <td>18+</td>
    548       <td></td>
    549     </tr>
    550     <tr>
    551       <td>SHA1withRSA/PSS</td>
    552       <td>23+</td>
    553       <td></td>
    554     </tr>
    555     <tr class="deprecated">
    556       <td>SHA224withDSA</td>
    557       <td>20&ndash;22</td>
    558       <td></td>
    559     </tr>
    560     <tr>
    561       <td>SHA224withECDSA</td>
    562       <td>20+</td>
    563       <td></td>
    564     </tr>
    565     <tr>
    566       <td>SHA224withRSA</td>
    567       <td>20+</td>
    568       <td></td>
    569     </tr>
    570     <tr>
    571       <td>SHA224withRSA/PSS</td>
    572       <td>23+</td>
    573       <td></td>
    574     </tr>
    575     <tr class="deprecated">
    576       <td>SHA256withDSA</td>
    577       <td>19&ndash;22</td>
    578       <td></td>
    579     </tr>
    580     <tr>
    581       <td>SHA256withECDSA</td>
    582       <td>19+</td>
    583       <td></td>
    584     </tr>
    585     <tr>
    586       <td>SHA256withRSA</td>
    587       <td>18+</td>
    588       <td></td>
    589     </tr>
    590     <tr>
    591       <td>SHA256withRSA/PSS</td>
    592       <td>23+</td>
    593       <td></td>
    594     </tr>
    595     <tr class="deprecated">
    596       <td>SHA384withDSA</td>
    597       <td>19&ndash;22</td>
    598       <td></td>
    599     </tr>
    600     <tr>
    601       <td>SHA384withECDSA</td>
    602       <td>19+</td>
    603       <td></td>
    604     </tr>
    605     <tr>
    606       <td>SHA384withRSA</td>
    607       <td>18+</td>
    608       <td></td>
    609     </tr>
    610     <tr>
    611       <td>SHA384withRSA/PSS</td>
    612       <td>23+</td>
    613       <td></td>
    614     </tr>
    615     <tr class="deprecated">
    616       <td>SHA512withDSA</td>
    617       <td>19&ndash;22</td>
    618       <td></td>
    619     </tr>
    620     <tr>
    621       <td>SHA512withECDSA</td>
    622       <td>19+</td>
    623       <td></td>
    624     </tr>
    625     <tr>
    626       <td>SHA512withRSA</td>
    627       <td>18+</td>
    628       <td></td>
    629     </tr>
    630     <tr>
    631       <td>SHA512withRSA/PSS</td>
    632       <td>23+</td>
    633       <td></td>
    634     </tr>
    635   </tbody>
    636 </table>
    637 
    638 <h3 id="SupportedSecretKeyFactories">SecretKeyFactory</h3>
    639 <table>
    640   <thead>
    641     <tr>
    642       <th>Algorithm</th>
    643       <th>Supported (API Levels)</th>
    644       <th>Notes</th>
    645     </tr>
    646   </thead>
    647   <tbody>
    648     <tr>
    649       <td>AES</td>
    650       <td>23+</td>
    651       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    652     </tr>
    653     <tr>
    654       <td>HmacSHA1</td>
    655       <td>23+</td>
    656       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    657     </tr>
    658     <tr>
    659       <td>HmacSHA224</td>
    660       <td>23+</td>
    661       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    662     </tr>
    663     <tr>
    664       <td>HmacSHA256</td>
    665       <td>23+</td>
    666       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    667     </tr>
    668     <tr>
    669       <td>HmacSHA384</td>
    670       <td>23+</td>
    671       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    672     </tr>
    673     <tr>
    674       <td>HmacSHA512</td>
    675       <td>23+</td>
    676       <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td>
    677     </tr>
    678   </tbody>
    679 </table>