-
Notifications
You must be signed in to change notification settings - Fork 160
RSA encryption padding change from PKCS1Padding to OAEPWithSHA-256And… #834
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
base: main
Are you sure you want to change the base?
Conversation
"("+ OLD_PKCS1_RSA_TRANSFORMATION +") for migration due to " + | ||
"InvalidKeyException with OAEP."); | ||
KeyStore.PrivateKeyEntry rsaKeyEntry = getRSAKeyEntry(); | ||
Cipher rsaPkcs1Cipher = Cipher.getInstance(OLD_PKCS1_RSA_TRANSFORMATION); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semgrep identified an issue in your code:
Weak cryptographic algorithm detected. The DES, 3DES, RC2, RC4, MD4, MD5, SHA1, BLOWFISH, Dual_EC_DRBG, and SHA1PRNG algorithms are considered insecure and should not be used. Using weak cryptographic algorithms can compromise the confidentiality and integrity of sensitive data. It is recommended to adopt only cryptographic features and algorithms offered by the Android platform that are internationally recognized as strong. It is also fundamental to ensure that the encryption parameters (crypto key, IV, etc.) are generated randomly using a cryptographically strong PRNG function. In addition, if it is needed to store an encryption parameter on the device, a secure storage mechanism like the Android KeyStore must be used.
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>
for false positive/ar <comment>
for acceptable risk/other <comment>
for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by android_weak_cryptographic_algorithm.
You can view more details about this finding in the Semgrep AppSec Platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primary digest used for the RSA-OAEP padding scheme is SHA-256, which is secure.
SHA1 is included only as a supported digest for the Mask Generation Function (MGF1), an internal component of OAEP.
This is a standard practice to ensure maximum compatibility across different Android OS versions and hardware security modules, as some implementations require SHA1 to be available for MGF1.
Log.d(TAG, "Attempting to decrypt AES key with PKCS1Padding ("+ | ||
OLD_PKCS1_RSA_TRANSFORMATION +") for migration."); | ||
KeyStore.PrivateKeyEntry rsaKeyEntry = getRSAKeyEntry(); | ||
Cipher rsaPkcs1Cipher = Cipher.getInstance(OLD_PKCS1_RSA_TRANSFORMATION); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semgrep identified an issue in your code:
Weak cryptographic algorithm detected. The DES, 3DES, RC2, RC4, MD4, MD5, SHA1, BLOWFISH, Dual_EC_DRBG, and SHA1PRNG algorithms are considered insecure and should not be used. Using weak cryptographic algorithms can compromise the confidentiality and integrity of sensitive data. It is recommended to adopt only cryptographic features and algorithms offered by the Android platform that are internationally recognized as strong. It is also fundamental to ensure that the encryption parameters (crypto key, IV, etc.) are generated randomly using a cryptographically strong PRNG function. In addition, if it is needed to store an encryption parameter on the device, a secure storage mechanism like the Android KeyStore must be used.
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>
for false positive/ar <comment>
for acceptable risk/other <comment>
for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by android_weak_cryptographic_algorithm.
You can view more details about this finding in the Semgrep AppSec Platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primary digest used for the RSA-OAEP padding scheme is SHA-256, which is secure.
SHA1 is included only as a supported digest for the Mask Generation Function (MGF1), an internal component of OAEP.
This is a standard practice to ensure maximum compatibility across different Android OS versions and hardware security modules, as some implementations require SHA1 to be available for MGF1.
// https://developer.android.com/reference/javax/crypto/Cipher.html | ||
@SuppressWarnings("SpellCheckingInspection") | ||
private static final String AES_TRANSFORMATION = "AES/GCM/NOPADDING"; | ||
private static final String OLD_PKCS1_RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding"; |
Check failure
Code scanning / CodeQL
Use of RSA algorithm without OAEP High
initialize an RSA cipher
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 21 days ago
To fix the problem, update the migration code to use OAEP padding for RSA decryption, if possible. This means replacing the use of "RSA/ECB/PKCS1Padding"
with "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"
(or another OAEP variant compatible with the legacy data). However, if the legacy data was encrypted with PKCS#1 padding, it cannot be decrypted with OAEP; in that case, the only safe option is to ensure the migration code is not exposed to untrusted input and is removed after migration. If you must keep the migration code, add comments to clarify its purpose and restrict its use. If you can re-encrypt legacy data with OAEP, do so and remove PKCS#1 padding support.
Best fix:
- Restrict the use of PKCS#1 padding to migration only, and add a clear comment explaining its legacy purpose.
- Ensure the migration code is not exposed to untrusted input.
- If possible, remove the migration code after all legacy data has been migrated.
- If you must keep the migration code, consider logging a warning and/or restricting its invocation.
Required changes:
- Add a comment above the definition and use of
OLD_PKCS1_RSA_TRANSFORMATION
explaining its legacy/migration-only purpose. - Optionally, add a runtime check or log to ensure the migration code is not used for new data.
- No new imports or methods are required.
-
Copy modified lines R60-R61 -
Copy modified lines R380-R381
@@ -57,6 +57,8 @@ | ||
// https://developer.android.com/reference/javax/crypto/Cipher.html | ||
@SuppressWarnings("SpellCheckingInspection") | ||
private static final String AES_TRANSFORMATION = "AES/GCM/NOPADDING"; | ||
// Legacy: Used only for migration of old AES keys encrypted with PKCS#1 padding. | ||
// Do NOT use for new encryption operations. Remove after migration is complete. | ||
private static final String OLD_PKCS1_RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding"; | ||
|
||
private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; | ||
@@ -375,6 +377,8 @@ | ||
try { | ||
byte[] encryptedOldAESBytes = Base64.decode(encodedOldAES, Base64.DEFAULT); | ||
KeyStore.PrivateKeyEntry rsaKeyEntry = getRSAKeyEntry(); | ||
// Legacy migration: Decrypt old AES key encrypted with PKCS#1 padding. | ||
// This block should only be used for migration and not for new data. | ||
Cipher rsaPkcs1Cipher = Cipher.getInstance(OLD_PKCS1_RSA_TRANSFORMATION); | ||
rsaPkcs1Cipher.init(Cipher.DECRYPT_MODE, rsaKeyEntry.getPrivateKey()); | ||
byte[] decryptedAESKey = rsaPkcs1Cipher.doFinal(encryptedOldAESBytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that was the PR which we are fixing to use OAEP padding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this usage is intentional and strictly limited to a one-time data migration path for existing users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets keep a backlog ticket to remove this once all users are migrated to the 3.10.0 or later
auth0/src/main/java/com/auth0/android/authentication/storage/CryptoUtil.java
Fixed
Show fixed
Hide fixed
auth0/src/main/java/com/auth0/android/authentication/storage/CryptoUtil.java
Fixed
Show resolved
Hide resolved
auth0/src/main/java/com/auth0/android/authentication/storage/CryptoUtil.java
Dismissed
Show dismissed
Hide dismissed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates the RSA encryption padding from PKCS1Padding to OAEPWithSHA-256AndMGF1Padding for improved security. The change includes backward compatibility handling to migrate existing PKCS1-encrypted AES keys to the new OAEP format.
- Changes RSA transformation from PKCS1Padding to OAEPWithSHA-256AndMGF1Padding
- Increases RSA key size from 2048 to 4096 bits
- Implements migration logic for existing PKCS1-encrypted AES keys to maintain compatibility
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
File | Description |
---|---|
CryptoUtil.java | Updates RSA transformation, key size, and implements migration logic for PKCS1 to OAEP transition |
CryptoUtilTest.java | Refactors tests to support new RSA transformation and adds migration test coverage |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
||
private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; | ||
private static final String ALGORITHM_RSA = "RSA"; | ||
private static final String ALGORITHM_AES = "AES"; | ||
private static final int AES_KEY_SIZE = 256; | ||
private static final int RSA_KEY_SIZE = 2048; | ||
private static final int RSA_KEY_SIZE = 4096; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Increasing RSA key size from 2048 to 4096 bits will significantly impact performance for key generation and encryption/decryption operations. Consider whether this change is necessary for security requirements or if 2048 bits is sufficient for the application's threat model.
private static final int RSA_KEY_SIZE = 4096; | |
private static final int RSA_KEY_SIZE = 2048; |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to increase the size ? Was this suggested by the security team ?
storage.store(KEY_ALIAS, newEncodedEncryptedAES); | ||
storage.remove(OLD_KEY_ALIAS); | ||
return decryptedAESKey; | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catching generic Exception is too broad and may hide specific error conditions. Consider catching specific exceptions like BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, etc., to handle different failure scenarios appropriately.
} catch (Exception e) { | |
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | KeyStoreException | UnrecoverableEntryException e) { |
Copilot uses AI. Check for mistakes.
throw new IncompatibleDeviceException(e); | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Catching generic Exception is too broad. This catch block should handle specific exceptions that can occur during RSA encryption or storage operations, such as CryptoException or IncompatibleDeviceException.
} catch (Exception e) { | |
} catch (InvalidKeyException | |
| NoSuchPaddingException | |
| IllegalBlockSizeException | |
| BadPaddingException | |
| KeyStoreException | |
| UnrecoverableEntryException | |
| CertificateException | |
| IOException | |
| ProviderException e) { |
Copilot uses AI. Check for mistakes.
// https://developer.android.com/reference/javax/crypto/Cipher.html | ||
@SuppressWarnings("SpellCheckingInspection") | ||
private static final String AES_TRANSFORMATION = "AES/GCM/NOPADDING"; | ||
private static final String OLD_PKCS1_RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment to state why OLD_PKCS1_RSA_TRANSFORMATION
is being used
@@ -124,7 +125,8 @@ KeyStore.PrivateKeyEntry getRSAKeyEntry() throws CryptoException, IncompatibleDe | |||
.setCertificateNotBefore(start.getTime()) | |||
.setCertificateNotAfter(end.getTime()) | |||
.setKeySize(RSA_KEY_SIZE) | |||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) | |||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) | |||
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope this setDigest addition was also reviewed by security ?
@utkrishtsahu The current implementation doesn't handle migration for existing users token . Please handle that and ensure it doesn't break |
RSA encryption padding change from PKCS1Padding to OAEPWithSHA-256And
Changes
Updated padding for RSA encryption from PKCS1Padding to OAEPWithSHA-256And also checked for migration for the same.
References
Testing
Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. Since this library has unit testing, tests should be added for new functionality and existing tests should complete without errors.
[X ] This change adds unit test coverage
[X ] This change adds integration test coverage
[ X] This change has been tested on the latest version of the platform/language or why not
Checklist
I have read the Auth0 general contribution guidelines
I have read the Auth0 Code of Conduct
All existing and new tests complete without errors