Skip to content

Commit

Permalink
URL safe base64 encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Jul 19, 2024
1 parent 4540703 commit 211765f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
26 changes: 19 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.openconext</groupId>
<artifactId>java-crypto</artifactId>
<version>1.0.4</version>
<version>1.0.5</version>
<packaging>jar</packaging>

<name>java-crypto</name>
Expand All @@ -18,23 +18,28 @@

<dependencies>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
<version>2.16.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<version>5.10.3</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -52,7 +57,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<version>0.8.12</version>
<executions>
<execution>
<goals>
Expand All @@ -71,7 +76,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.3.0</version>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-versions</id>
Expand All @@ -94,7 +99,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
Expand All @@ -113,6 +118,13 @@
</extension>
</extensions>
</build>
<repositories>
<repository>
<id>maven_central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
</repositories>

<distributionManagement>
<repository>
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/crypto/RSAKeyStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@


import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;


/**
* Utility class for encrypting and decrypting secrets with RSA private / public keys
Expand Down Expand Up @@ -44,7 +45,7 @@ public RSAKeyStore(String publicKeyContent, boolean ignore) {
publicKeyContent = stripPublicKey(publicKeyContent);

KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyContent));
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyContent));
this.publicKey = kf.generatePublic(keySpecX509);
this.privateKey = null;
}
Expand All @@ -61,7 +62,7 @@ public RSAKeyStore(String privateKeyContent) {

KeyFactory kf = KeyFactory.getInstance("RSA");

PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyContent));
this.privateKey = kf.generatePrivate(keySpecPKCS8);
this.publicKey = null;
}
Expand All @@ -76,7 +77,7 @@ public String encryptAndEncode(String secret) {
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] secretMessageBytes = secret.getBytes(Charset.defaultCharset());
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
return Base64.getEncoder().encodeToString(encryptedMessageBytes);
return new String(Base64.encodeBase64(encryptedMessageBytes, false, true));
}

@Override
Expand All @@ -87,19 +88,19 @@ public String decodeAndDecrypt(String encodedEncryptedSecret) {
}
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedMessageBytes = decryptCipher.doFinal(Base64.getDecoder().decode(encodedEncryptedSecret));
byte[] decryptedMessageBytes = decryptCipher.doFinal(Base64.decodeBase64(encodedEncryptedSecret));
return new String(decryptedMessageBytes, StandardCharsets.UTF_8);
}

@Override
public boolean isEncryptedSecret(String input) {
// (int) Math.ceil(2048.0/ 8 / 3) * 4 = 344;
return input.length() == 344 && this.validBase64(input);
// (int) Math.ceil(2048.0/ 8 / 3) * 4 = 344 - 2 = 342;
return input.length() == 342 && this.validBase64(input);
}

private boolean validBase64(String input) {
try {
Base64.getDecoder().decode(input);
Base64.decodeBase64(input);
return true;
} catch (IllegalArgumentException e) {
return false;
Expand Down
5 changes: 1 addition & 4 deletions src/test/java/crypto/KeyStoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,11 @@ void isEncryptedSecret() {
String encryptedSecret = keyStore.encryptAndEncode(secret);

assertTrue(keyStore.isEncryptedSecret(encryptedSecret));

assertFalse(keyStore.isEncryptedSecret("!"));
assertFalse(keyStore.isEncryptedSecret("!".repeat(344)));
//Corner case - waiting for a smart tester to pick this up
assertTrue(keyStore.isEncryptedSecret("a".repeat(344)));
assertTrue(keyStore.isEncryptedSecret("a".repeat(342)));
}


private void doEncryptAndDecrypt(KeyStore encryptionKeyStore, KeyStore decryptionKeyStore) {
String secret = UUID.randomUUID().toString();
String encryptedSecret = encryptionKeyStore.encryptAndEncode(secret);
Expand Down

0 comments on commit 211765f

Please sign in to comment.