Skip to content

Commit

Permalink
AES GCM/CTR Encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroigor committed Oct 24, 2019
1 parent 86ad410 commit fb0b13d
Showing 1 changed file with 25 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.quarkus.vertx.http.runtime.security;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.jboss.logging.Logger;
Expand All @@ -25,10 +28,13 @@
public class PersistentLoginManager {

private static final Logger log = Logger.getLogger(PersistentLoginManager.class);
private static final String ENC_ALGORITHM = "AES/GCM/NoPadding";
private static final int ENC_TAG_LENGTH = 128;

private final SecretKey secretKey;
private final String cookieName;
private final long timeoutMillis;
private final SecureRandom secureRandom = new SecureRandom();

public PersistentLoginManager(String encryptionKey, String cookieName, long timeoutMillis) {
try {
Expand Down Expand Up @@ -56,9 +62,15 @@ public RestoreResult restore(RoutingContext context) {
}
String val = existing.getValue();
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String result = new String(cipher.doFinal(Base64.getDecoder().decode(val)), StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(ENC_ALGORITHM);
ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(val.getBytes(StandardCharsets.UTF_8)));
int ivLength = byteBuffer.get();
byte[] iv = new byte[ivLength];
byteBuffer.get(iv);
byte[] encrypted = new byte[byteBuffer.remaining()];
byteBuffer.get(encrypted);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(ENC_TAG_LENGTH, iv));
String result = new String(cipher.doFinal(encrypted));
int sep = result.indexOf(":");
if (sep == -1) {
return null;
Expand All @@ -81,18 +93,21 @@ public void save(SecurityIdentity identity, RoutingContext context, RestoreResul
}
}
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

Cipher cipher = Cipher.getInstance(ENC_ALGORITHM);
byte[] iv = new byte[12];
secureRandom.nextBytes(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(ENC_TAG_LENGTH, iv));
StringBuilder contents = new StringBuilder();
//TODO: do we need random padding?
long timeout = System.currentTimeMillis() + timeoutMillis;
contents.append(timeout);
contents.append(":");
contents.append(identity.getPrincipal().getName());

cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String cookieValue = Base64.getEncoder()
.encodeToString(cipher.doFinal(contents.toString().getBytes(StandardCharsets.UTF_8)));
byte[] encrypted = cipher.doFinal(contents.toString().getBytes(StandardCharsets.UTF_8));
ByteBuffer message = ByteBuffer.allocate(1 + iv.length + encrypted.length);
message.put((byte) iv.length);
message.put(iv);
message.put(encrypted);
String cookieValue = Base64.getEncoder().encodeToString(message.array());
context.addCookie(Cookie.cookie(cookieName, cookieValue).setPath("/"));
} catch (Exception e) {
throw new RuntimeException(e);
Expand Down

0 comments on commit fb0b13d

Please sign in to comment.