Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key management updates in "Testing cryptography", "Testing data storage" for iOS and Android #1884

Closed
wants to merge 12 commits into from

Conversation

vixentael
Copy link
Contributor

@vixentael vixentael commented Mar 26, 2021

I slightly refreshed crypto chapter:

  • Updated "Protecting Keys in Memory" adding more information of keys clean up and key wrapping techniques.
  • Clarified IV usage, add note about popular mistake of copy-pasting example code with hardcoded IVs from OSS crypto libs.
  • Mentioned BLAKE3.
  • Added @veorq cryptocoding guidelines as reference for zeroing memory.

These changes were discussed with @sushi2k and @julepka in a separate doc.


Thank you for submitting a Pull Request to the Mobile Security Testing Guide. Please make sure that:

  • Your contribution is written in the 2nd person (e.g. you)
  • Your contribution is written in an active present form for as much as possible.
  • You have made sure that the reference section is up to date (e.g. please add sources you have used, make sure that the references to MITRE/MASVS/etc. are up to date)
  • Your contribution has proper formatted markdown and/or code
  • Any references to website have been formatted as [TEXT](URL “NAME”)
  • You verified/tested the effectiveness of your contribution (e.g.: is the code really an effective remediation? Please verify it works!)

* Update "Protecting Keys in Memory" adding more information of keys clean up and key wrapping techniques. 
* Clarify IV usage, add note about popular mistake of copy-pasting example code with hardcoded IVs from OSS crypto libs.
* Mention Blake3
* Add @veorq cryptocoding guidelines as reference for zeroing memory.

These changes were discussed with @sushi2k and @julepka in a separate doc.
@vixentael
Copy link
Contributor Author

markdown check is failing, but due to links in other places
Screenshot 2021-03-26 at 15 44 22

@vixentael
Copy link
Contributor Author

the Great BLAKE creator @veorq told me that BLAKE should be written as BLAKE not Blake. I obey.

Copy link
Collaborator

@cpholguera cpholguera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @vixentael, thanks a lot for the nice PR. Please take a look at the change suggestions and the comments. There sre mainly 2 points where a little bit research would be great. It's very nice that you brought this up since the guide really needs to give clearer recommendations on this. I hope the reference links I've included help you come up with something. Could you please enhance the section with that? Thanks a lot in advance!

Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
vixentael and others added 2 commits March 31, 2021 01:13
Co-authored-by: cpholguera <perezholguera@gmail.com>
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
@cpholguera
Copy link
Collaborator

Short update: half review has already happened. Hopefully I can send you some feedback this week. We need to ensure that we properly address these topics, we might have to relocate and merge some info with other parts of the guide. I'll let you know as soon as I have something new.

btw. thanks for the link to the key wrapping, that's what I was looking for, I couldn't recall the technique myself and I'd like to ensure that we keep using standard wording/naming, etc.

@vixentael
Copy link
Contributor Author

thank you @cpholguera!
I'm open to discussion here and in owasp slack (@vixentael)

Copy link
Collaborator

@cpholguera cpholguera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vixentael, the review took some time since you're touching very interesting points here. I was thinking that this give us the chance to improve the guide even more, so I wanted to carefully craft the suggestions. I hope you like them and can help us out with a little refactoring / update of some sections. We should keep this chapter "general" and move the specifics to the Android/iOS chapters.

I'd understand if something is not completely clear, please feel free to discuss here or in Slack :)

Thanks a lot again for taking care of this!

Comment on lines 163 to 164
- Make sure that all cryptographic actions and the keys itself remain in the Trusted Execution Environment (e.g. use [Android Keystore](https://developer.android.com/training/articles/keystore.html "Android keystore system")) or [Secure Enclave](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave "Storing Keys in the Secure Enclave") (e.g. use the Keychain and when you sign, use ECDHE).
- If keys are necessary which are outside of the TEE / SE, make sure keys are protected using multi-layered approach. For example, data encryption key (DEK) can be encrypted with key encryption key (KEK) stored in Keychain / Keystore, thus DEK is stored encrypted. This key wrapping technique requires reading KEK first and then decrypting DEK before usage. An illustration of this approach is [EncryptedSharedPreferences from androidx.security.crypto package](https://developer.android.com/jetpack/androidx/releases/security "androidx.security.crypto API reference"). Another approach of protecting keys is obfuscation: obfuscate DEK and de-obfuscate it before usage.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Make sure that all cryptographic actions and the keys itself remain in the Trusted Execution Environment (e.g. use [Android Keystore](https://developer.android.com/training/articles/keystore.html "Android keystore system")) or [Secure Enclave](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave "Storing Keys in the Secure Enclave") (e.g. use the Keychain and when you sign, use ECDHE).
- If keys are necessary which are outside of the TEE / SE, make sure keys are protected using multi-layered approach. For example, data encryption key (DEK) can be encrypted with key encryption key (KEK) stored in Keychain / Keystore, thus DEK is stored encrypted. This key wrapping technique requires reading KEK first and then decrypting DEK before usage. An illustration of this approach is [EncryptedSharedPreferences from androidx.security.crypto package](https://developer.android.com/jetpack/androidx/releases/security "androidx.security.crypto API reference"). Another approach of protecting keys is obfuscation: obfuscate DEK and de-obfuscate it before usage.
- Make sure that all cryptographic actions and the keys itself remain in the Trusted Execution Environment (e.g. use [Android Keystore](https://developer.android.com/training/articles/keystore.html "Android keystore system")) or [Secure Enclave](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave "Storing Keys in the Secure Enclave") (e.g. use the Keychain). Refer to the [Android Data Storage](0x05d-Testing-Data-Storage.md#storing-a-key---example) and [iOS Data Storage](0x06d-Testing-Data-Storage.md#the-keychain) chapters for more information.

This point is addressing one special case of the previous point for Android, I'd suggest to remove it since the previous point covers it. The current paragraph should be reduced and the specifics moved/merged to their corresp. chapters.

You can use the info from the deleted paragraph to update Android Data Storage - Storing a key section. We need a nice overview / clear recommendation there (e.g. most secure if it never leaves the KeyStore, 2nd most secure if using EncryptedPreferences, etc.). You could take the chance to introduce the official term "Envelope encryption" from the site you've sent me which refers to Google.

Maybe it could be a nice idea to include another example, since this is also good to know for other kind of apps such as the "React Native"-based ones (and goes in-line with our statement/recommendation here):

Unfortunately I could not find more examples for other frameworks, only this lib for Flutter , but it has a custom implementation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm realizing now that the location of the mentioned information is not yet consistent. The iOS chapter should have an introductory section regarding iOS Data Storage (reflecting the Android one), instead of inside the test case.

This refactoring should be eventually made. If you want please go ahead and move/consolidate that info (as part of a new PR).

Comment on lines 165 to 166
- Make sure that keys live in memory for the shortest time possible. Ideally, keys should be read/allocated right before usage and clean up after usage or in case of error. Avoid storing keys in constants.
- Consider zeroing out and nullify keys after successful cryptographic operation and in case of error. Unfortunately, there are certain limitations of realibly cleaning up secret data in languages with garbage collector (Java) and immutable `String` (Swift, Objective-C, Kotlin). [Java Cryptography Architecture Reference Guide](https://docs.oracle.com/en/java/javase/16/security/java-cryptography-architecture-jca-reference-guide.html#GUID-C9F76AFB-6B20-45A7-B84F-96756C8A94B4 "Java Cryptography Architecture (JCA) Reference Guide") suggests using `char[]` instead of `String` for storing sensitive data, and nullify array after usage. [Apple Secure Coding Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/SecurityDevelopmentChecklists/SecurityDevelopmentChecklists.html "Security Development Checklists") also suggests zeroing passwords after usage, but provides no recommended ways of doing this. Consider using `NSMutableData` for storing secrets on Swift/Objective-C and use [`resetBytes(in:)` method](https://developer.apple.com/documentation/foundation/nsmutabledata/1415526-resetbytes "NSMutableData resetBytes(in:) API reference") for zeroing. Also, see [Clean memory of secret data](https://github.com/veorq/cryptocoding#clean-memory-of-secret-data/ "The Cryptocoding Guidelines by @veorq: Clean memory of secret data") for reference.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Make sure that keys live in memory for the shortest time possible. Ideally, keys should be read/allocated right before usage and clean up after usage or in case of error. Avoid storing keys in constants.
- Consider zeroing out and nullify keys after successful cryptographic operation and in case of error. Unfortunately, there are certain limitations of realibly cleaning up secret data in languages with garbage collector (Java) and immutable `String` (Swift, Objective-C, Kotlin). [Java Cryptography Architecture Reference Guide](https://docs.oracle.com/en/java/javase/16/security/java-cryptography-architecture-jca-reference-guide.html#GUID-C9F76AFB-6B20-45A7-B84F-96756C8A94B4 "Java Cryptography Architecture (JCA) Reference Guide") suggests using `char[]` instead of `String` for storing sensitive data, and nullify array after usage. [Apple Secure Coding Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/SecurityDevelopmentChecklists/SecurityDevelopmentChecklists.html "Security Development Checklists") also suggests zeroing passwords after usage, but provides no recommended ways of doing this. Consider using `NSMutableData` for storing secrets on Swift/Objective-C and use [`resetBytes(in:)` method](https://developer.apple.com/documentation/foundation/nsmutabledata/1415526-resetbytes "NSMutableData resetBytes(in:) API reference") for zeroing. Also, see [Clean memory of secret data](https://github.com/veorq/cryptocoding#clean-memory-of-secret-data/ "The Cryptocoding Guidelines by @veorq: Clean memory of secret data") for reference.
- Make sure that keys live in memory for the shortest time possible and consider zeroing out and nullifying keys after successful cryptographic operations, or in case of error. For more detailed information refer to sections [Testing Memory for Sensitive Data](0x05d-Testing-Data-Storage.md#checking-memory-for-sensitive-data-mstg-storage-10) and [Checking Memory for Sensitive Data](0x05d-Testing-Data-Storage.md#checking-memory-for-sensitive-data-mstg-storage-10) for Android and iOS respectively.

To keep it simple and general (since we're in the general guide here), I suggest to reduce these two points to the suggestion and use the removed information to update these sections:

Also consider renaming the section from "Checking Memory for Sensitive Data" to "Testing Memory for Sensitive Data" for consistency.

@vixentael vixentael changed the title Key zeroing updates in Mobile app cryptography Key management updates in "Testing cryptography", "Testing data storage" for iOS and Android Apr 20, 2021
@vixentael
Copy link
Contributor Author

vixentael commented Apr 20, 2021

@cpholguera thank you for the review! I totally support the idea of having general details in general guide and moving specific details into iOS/Android guides.


Things I've done:

0x04g-Testing-Cryptography

  1. Reduced details in key management chapter. I left only cross-platform things and introduced envelope encryption technique (because it's 100% cross platform :) ).

0x05d-Testing-Data-Storage (Android)

  1. Updated Android "Storing a cryptographic key: techniques" chapter. I didn't add a lot of info, but added more headers to make it more structured. I updated "key clean up" info, described envelope encryption, linked with Android EncryptedSharedPreferences library, and mentioned key obfuscation.

  2. Renamed "Checking Memory for Sensitive Data" to "Testing Memory for Sensitive Data", and fixed all mentions/links of the previous name.

0x06d-Testing-Data-Storage (iOS)

  1. Added short details about different key storage ways into "Testing Local Data Storage", and some info about sensitive data clean up into "Testing Memory for Sensitive Data".

Things I haven't done:

  1. I haven't used react native libs examples that you've mentioned. Because we decided to have the general chapter more general, so it doesn't have links to platform-specific libraries now. And AFAIK, MSTG is targeted on native apps mainly. Where do you see RN libraries fit?
  2. As iOS testing guide doesn't have a Theory Overview chapter (yet), I decided to add just small pieces about key management into test cases (not perfect, but works for now). I am up to making a separate PR with theory chapter that describes preferred key management ways for iOS similar to what we have for Android. But before me doing that, let's agree on this PR first :)

@vixentael
Copy link
Contributor Author

@cpholguera I mean no rush, but what do you think about the latest update? I'd like to get it sorted and to move to updating iOS crypto part next.

@cpholguera
Copy link
Collaborator

Hi, we've been very busy with the MASVS release and now on leave until June. We'll go back to this one then. Thanks for the patience!

@vixentael
Copy link
Contributor Author

@cpholguera no mean to rush, but Apple has introduced AES.KeyWrap API on the latest WWDC :) (No docs now, but it's similar to https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey)

It means that after merging this PR, I'll have even more things-to-write about in a new chapter in iOS Testing guide :)

@cpholguera
Copy link
Collaborator

Sounds very nice, is there a video for that?
Please feel free to open an issue 😉

Thanks for your patience, we hope we can get back to the PRs soon. There's a lot going on right now. We'll announce something soon, I'm sure you'll like it :)

@cpholguera
Copy link
Collaborator

Hi @vixentael, just to let you know: we did not forget about this PR. As you know we're currently performing a big refactor of the MASVS and your content in this PR is helping us a lot currently since we're taking a look at V2 specifically :)

Thanks for your patience!

@vixentael
Copy link
Contributor Author

hi @cpholguera thank you for the update! I keep an eye on discussions in MASVS, but I'm also available in OWASP slack, so if any questions – i'd be happy to help in shaping crypto requirements.

Copy link
Collaborator

@cpholguera cpholguera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @vixentael and sorry about the long wait. I hope you're doing well.

I'm proposing changes I got from a review I started doing some time ago. Nothing for you to change for now. @TheDauntless will help with the review by first reviewing my review (if that makes sense :) ).

However, feel free to comment if you want to.

In order to securely store symmetric keys on devices running on Android 5.1 (API level 22) or lower, we need to generate a public/private key pair. We encrypt the symmetric key using the public key and store the private key in the `AndroidKeyStore`. The encrypted symmetric key can encoded using base64 and stored in the `SharedPreferences`. Whenever we need the symmetric key, the application retrieves the private key from the `AndroidKeyStore` and decrypts the symmetric key.

Envelope encryption, or key wrapping, is a similar approach that uses symmetric encryption to encapsulate key material. Data encryption keys (DEK) can be encrypted with key encryption keys (KEK) which is securely stored. Encrypted DEK can be stored in `SharedPreferences` or written in files. When required, application reads KEK, then decrypts DEK. Refer to [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#encrypting-stored-keys "OWASP Cryptographic Storage Cheat Sheet: Encrypting Stored Keys") to learn more about encrypting cryptographic keys.

Also, as the illustration of this approach, refer to the [EncryptedSharedPreferences from androidx.security.crypto package](https://developer.android.com/jetpack/androidx/releases/security "androidx.security.crypto API reference").
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x04g-Testing-Cryptography.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x06d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@TheDauntless TheDauntless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some additional changes.

Document/0x06d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x05d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Document/0x06d-Testing-Data-Storage.md Outdated Show resolved Hide resolved
Co-authored-by: Jeroen Beckers <me.githbub@dauntless.be>
Copy link
Collaborator

@cpholguera cpholguera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vixentael this is awesome content, we've applied some fixes and will merge. We hope to have your support for the upcoming MSTG refactoring!

@cpholguera
Copy link
Collaborator

Closing. Now replaced by #2127 keeping the original commits.

@cpholguera cpholguera closed this Jun 28, 2022
@vixentael vixentael deleted the patch-1 branch June 29, 2022 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants