Skip to content

Commit

Permalink
OIDC state algorithm update (#10275)
Browse files Browse the repository at this point in the history
* security enhancement

* add missing params

* change doFinal per

https://gist.github.com/patrickfav/7e28d4eb4bf500f7ee8012c4a0cf7bbf

* add iv to encrypted value

* Update src/main/java/edu/harvard/iq/dataverse/util/StringUtil.java

Co-authored-by: Oliver Bertuch <poikilotherm@users.noreply.github.com>

---------

Co-authored-by: Oliver Bertuch <poikilotherm@users.noreply.github.com>
  • Loading branch information
qqmyers and poikilotherm committed Mar 5, 2024
1 parent c6568ca commit 0390b38
Showing 1 changed file with 26 additions and 8 deletions.
34 changes: 26 additions & 8 deletions src/main/java/edu/harvard/iq/dataverse/util/StringUtil.java
Expand Up @@ -2,9 +2,13 @@

import edu.harvard.iq.dataverse.authorization.providers.oauth2.OAuth2LoginBackingBean;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
Expand All @@ -19,6 +23,7 @@
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -117,26 +122,37 @@ public static List<String> htmlArray2textArray(List<String> htmlArray) {
return cleanTextArray;
}

private final static SecureRandom secureRandom = new SecureRandom();
// 12 bytes is recommended by GCM spec
private final static int GCM_IV_LENGTH = 12;

/**
* Generates an AES-encrypted version of the string. Resultant string is URL safe.
* @param value The value to encrypt.
* @param password The password.
* @return encrypted string, URL-safe.
*/
public static String encrypt(String value, String password ) {

byte[] baseBytes = value.getBytes();
try {
Cipher aes = Cipher.getInstance("AES");
byte[] iv = new byte[GCM_IV_LENGTH]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
Cipher aes = Cipher.getInstance("AES/GCM/NoPadding");
final SecretKeySpec secretKeySpec = generateKeyFromString(password);
aes.init(Cipher.ENCRYPT_MODE, secretKeySpec);
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv);
aes.init(Cipher.ENCRYPT_MODE, secretKeySpec, parameterSpec);
byte[] encrypted = aes.doFinal(baseBytes);
String base64ed = new String(Base64.getEncoder().encode(encrypted));
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + encrypted.length);
byteBuffer.put(iv);
byteBuffer.put(encrypted);
String base64ed = new String(Base64.getEncoder().encode(byteBuffer.array()));
return base64ed.replaceAll("\\+", ".")
.replaceAll("=", "-")
.replaceAll("/", "_");

} catch ( InvalidKeyException | NoSuchAlgorithmException | BadPaddingException
| IllegalBlockSizeException | NoSuchPaddingException | UnsupportedEncodingException ex) {
| IllegalBlockSizeException | NoSuchPaddingException | UnsupportedEncodingException | InvalidAlgorithmParameterException ex) {
Logger.getLogger(OAuth2LoginBackingBean.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException(ex);
}
Expand All @@ -149,13 +165,15 @@ public static String decrypt(String value, String password ) {

byte[] baseBytes = Base64.getDecoder().decode(base64);
try {
Cipher aes = Cipher.getInstance("AES");
aes.init( Cipher.DECRYPT_MODE, generateKeyFromString(password));
byte[] decrypted = aes.doFinal(baseBytes);
Cipher aes = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, baseBytes, 0, GCM_IV_LENGTH);
aes.init( Cipher.DECRYPT_MODE, generateKeyFromString(password),gcmIv);
byte[] decrypted = aes.doFinal(baseBytes,GCM_IV_LENGTH, baseBytes.length - GCM_IV_LENGTH);
return new String(decrypted);

} catch ( InvalidKeyException | NoSuchAlgorithmException | BadPaddingException
| IllegalBlockSizeException | NoSuchPaddingException | UnsupportedEncodingException ex) {
| IllegalBlockSizeException | NoSuchPaddingException | UnsupportedEncodingException | InvalidAlgorithmParameterException ex) {
Logger.getLogger(OAuth2LoginBackingBean.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException(ex);
}
Expand Down

0 comments on commit 0390b38

Please sign in to comment.