10 Commits
Author SHA1 Message Date
Xiao 16149a8dec README.md aktualisieren 2026-08-07 03:12:54 +08:00
Xiao 3f93b73ea0 README.md aktualisieren 2026-08-07 03:11:27 +08:00
Xiao 02aa2c8776 Update isNull.java (#44)
ez
2026-07-14 16:10:38 -04:00
Xiao c8e9b50883 fix leak (#43)
- add SLF4J as a dependency in pom.xml
- replace System.out.println with log.warn (prevent leak)
2026-07-14 16:03:52 -04:00
Xiao 273f10a987 Update XACryptoException.java (#41)
#SIMPLEST FIX EVER lmao
2026-07-14 15:50:25 -04:00
Xiao 999c99f166 Update Factories.java (#40) 2026-07-14 15:46:49 -04:00
Xiao f54b14cc9c Update README.md 2026-07-09 22:32:50 -04:00
Xiao 62b2848ab2 this is why you test things, before commiting to main, kids. 2026-07-05 14:08:16 -04:00
Xiao 06504b83d5 whoops! 2026-07-05 14:03:30 -04:00
xiao 9566323ac7 Update pom.xml
i forgot to update this before erelease lol, i changed this right before i compiled but not before commit!
2026-07-04 14:44:27 -04:00
8 changed files with 75 additions and 24 deletions
+5 -1
View File
@@ -1,6 +1,10 @@
A multi-purpose Cryptography library in Java. Working on it day by day, slowly. Someday this will be complete, today is not that day. A multi-purpose Cryptography library in Java. Working on it day by day, slowly. Someday this will be complete, today is not that day.
To be clear, this is **NOT** mean't to be a replacement/alternative to BouncyCastle. Instead, it is meant to include what BouncyCastle does not have. No code was taken from OpenSSL or BouncyCastle for that reason. To be clear, this is **NOT** mean't to be a replacement/alternative to BouncyCastle. Instead, it is meant to include what BouncyCastle does not have. No code was taken from OpenSSL or BouncyCastle for that reason.
We are (soon to be) DMCA-protected: https://www.dmca.com/r/8e2yr97
Yes. We will advertise Microsoft products for free via variable names.
Use `setopt interactivecomments` (zsh only) to allow using `#` for comments if you see errors like `zsh: command not found: #` Use `setopt interactivecomments` (zsh only) to allow using `#` for comments if you see errors like `zsh: command not found: #`
Ensure Java + javac are installed, on MacOS it can be installed with Homebrew by running `brew install openjdk` Ensure Java + javac are installed, on MacOS it can be installed with Homebrew by running `brew install openjdk`
@@ -13,4 +17,4 @@ To compile (these commands should work universally):
2. cd XACrypto # enter the directory 2. cd XACrypto # enter the directory
3. mvn clean package # first clean the directory, then package it into a jar 3. mvn clean package # first clean the directory, then package it into a jar
You should find the built jar at target/XACrypto-1.0-SNAPSHOT.jar You should find the built jar at target/xacrypto-\<version\>.jar
+8 -2
View File
@@ -8,7 +8,7 @@
<groupId>de.caydenno1.xacrypto</groupId> <groupId>de.caydenno1.xacrypto</groupId>
<artifactId>xacrypto</artifactId> <artifactId>xacrypto</artifactId>
<version>2026.06.19_R1</version> <version>2026.07.04_R1</version>
<name>XACrypto</name> <name>XACrypto</name>
<description>A multi-purpose Cryptography library in Java.</description> <description>A multi-purpose Cryptography library in Java.</description>
@@ -55,6 +55,12 @@
</dependencyManagement> </dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
@@ -144,4 +150,4 @@
</plugins> </plugins>
</build> </build>
</project> </project>
@@ -1,6 +1,8 @@
package de.caydenno1.xacrypto.hash.sha; package de.caydenno1.xacrypto.hash.sha;
import de.caydenno1.xacrypto.misc.Constants; import de.caydenno1.xacrypto.misc.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -8,9 +10,10 @@ import static de.caydenno1.xacrypto.hash.sha.Shared.INT2BYTE;
import static de.caydenno1.xacrypto.hash.sha.Shared.hex; import static de.caydenno1.xacrypto.hash.sha.Shared.hex;
public class SHA0 { public class SHA0 {
// we really only need one file. very simple code private static final Logger log = LoggerFactory.getLogger(SHA0.class);
public static byte[] hash(byte[] data){ public static byte[] hash(byte[] data){
System.out.println("Beware, SHA0 is deprecated and cryptographically broken. Use at your own risk."); log.warn("SHA0 is deprecated and cryptographically broken. Use at your own risk.");
byte[] padded = Shared.pad(data); byte[] padded = Shared.pad(data);
int a0 = Constants.SHA_H[0], a1 = Constants.SHA_H[1], a2 = Constants.SHA_H[2], a3 = Constants.SHA_H[3], a4 = Constants.SHA_H[4]; int a0 = Constants.SHA_H[0], a1 = Constants.SHA_H[1], a2 = Constants.SHA_H[2], a3 = Constants.SHA_H[3], a4 = Constants.SHA_H[4];
@@ -17,7 +17,7 @@ public class XACryptoException extends Exception {
} }
public XACryptoException(String res, int iid) { public XACryptoException(String res, int iid) {
super(res); super(res);
this.id = iid; this.id = iid & 0xFF;
} }
public XACryptoException(String[] pnts, byte id){ public XACryptoException(String[] pnts, byte id){
super(String.join("|", pnts)); super(String.join("|", pnts));
@@ -10,13 +10,6 @@ public class isNull {
return Objects.isNull(v) || v == null || v == alt; return Objects.isNull(v) || v == null || v == alt;
} }
public static boolean isValidText(String s) { public static boolean isValidText(String s) {
if (s.isBlank() || s.trim().isEmpty()) return false; return !isNull(s) && !s.isBlank();
switch (s) {
case "":
case null:
return false;
default:
return true;
}
}; };
} }
@@ -23,19 +23,56 @@ public class Factories {
public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM SerpentGCM(byte[] key) throws XACryptoException { return new SerpentGCM(key); } public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM SerpentGCM(byte[] key) throws XACryptoException { return new SerpentGCM(key); }
} }
private static volatile boolean ecbOptIn = false;
/**
* Enables the use of ECB mode.
*
* <p><strong>Warning:</strong> ECB mode is insecure for
* almost all applications because identical plaintext blocks
* produce identical ciphertext blocks, leaking data patterns.
*
* <p>This method exists solely for backwards compatibility.
* Prefer {@link Factories.GCM} or another secure encryption mode.
* The contributor that has written this wishes to remain anonymous.
*/
public static void allowInsecureECB() {
ecbOptIn = true;
}
private static void checkECBenabled() throws XACryptoException {
if (!ecbOptIn) {
throw new XACryptoException(
"ECB mode is not secure because it can leak data patterns. Call Factories.allowInsecureECB() before using ECB."
);
}
}
/**
* Provides ECB mode cipher factories.
*
* <p><strong>Warning:</strong> ECB mode is insecure because identical
* plaintext blocks produce identical ciphertext blocks, leaking data patterns.
*
* <p>This class requires opt-in using
* {@link Factories#allowInsecureECB()} and exists only for backwards compatibility.
*
* @deprecated Use GCM or another secure encryption mode instead.
*/
@Deprecated
public static class ECB { public static class ECB {
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless Blowfish(byte[] key) throws XACryptoException { return new BlowfishECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless Blowfish(byte[] key) throws XACryptoException { checkECBenabled(); return new BlowfishECB(key); }
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Aria(byte[] key) throws XACryptoException { return new AriaECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Aria(byte[] key) throws XACryptoException { checkECBenabled(); return new AriaECB(key); }
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless SM4(byte[] key) throws XACryptoException { return new SM4ECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless SM4(byte[] key) throws XACryptoException { checkECBenabled(); return new SM4ECB(key); }
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB AES(byte[] key) throws XACryptoException { return new AESECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB AES(byte[] key) throws XACryptoException { checkECBenabled(); return new AESECB(key); }
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Twofish(byte[] key) throws XACryptoException { return new TwofishECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Twofish(byte[] key) throws XACryptoException { checkECBenabled(); return new TwofishECB(key); }
public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB RC6ECB(byte[] key) throws XACryptoException { return new RC6ECB(key); } public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB RC6ECB(byte[] key) throws XACryptoException { checkECBenabled(); return new RC6ECB(key); }
//public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless CamelliaECB(byte[] key) throws XACryptoException { return new CamelliaECB(key); } //public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless CamelliaECB(byte[] key) throws XACryptoException { return new CamelliaECB(key); }
} }
} }
@@ -1,12 +1,16 @@
package de.caydenno1.xacrypto.zekerrijndael.GCM; package de.caydenno1.xacrypto.zekerrijndael.GCM;
import de.caydenno1.xacrypto.misc.ToM; import de.caydenno1.xacrypto.misc.ToM;
import de.caydenno1.xacrypto.misc.XACryptoException; import de.caydenno1.xacrypto.misc.XACryptoException;
import de.caydenno1.xacrypto.misc.isNull; import de.caydenno1.xacrypto.misc.isNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
public class GCM { public class GCM {
private static final Logger log = LoggerFactory.getLogger(GCM.class);
private final BlockCipher cip; private final BlockCipher cip;
private final GHASH gh; private final GHASH gh;
@@ -63,7 +67,7 @@ public class GCM {
if (!corr && !override) { if (!corr && !override) {
throw new XACryptoException("GCM tag does not match. Use Flag -override to ignore this.",(byte)-1); throw new XACryptoException("GCM tag does not match. Use Flag -override to ignore this.",(byte)-1);
} else if (!corr) { } else if (!corr) {
System.out.println("GCM tag does not match. Overriding..."); log.warn("GCM tag does not match. Overriding...");
} }
return gctr(inc32(J0), ct); return gctr(inc32(J0), ct);
@@ -4,6 +4,8 @@ import de.caydenno1.xacrypto.misc.XACryptoException;
import de.caydenno1.xacrypto.zekerrijndael.GCM.GHASH; import de.caydenno1.xacrypto.zekerrijndael.GCM.GHASH;
import de.caydenno1.xacrypto.zekerrijndael.GCM.AES; import de.caydenno1.xacrypto.zekerrijndael.GCM.AES;
import de.caydenno1.xacrypto.zekerrijndael.GCM.Result; import de.caydenno1.xacrypto.zekerrijndael.GCM.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects; import java.util.Objects;
@@ -16,8 +18,10 @@ interface AESCipher {
} }
public class AESGCM implements AESCipher { public class AESGCM implements AESCipher {
private static final Logger log = LoggerFactory.getLogger(AESGCM.class);
public Result encryptBlock(byte[] pln, byte[] key, byte[] nonce, byte[] aad) throws XACryptoException { public Result encryptBlock(byte[] pln, byte[] key, byte[] nonce, byte[] aad) throws XACryptoException {
System.out.println("WARNING! AESGCM may not be fully functional and partially broken. I am unsure if it fully works or not."); log.warn("AESGCM may not be fully functional and partially broken. I am unsure if it fully works or not.");
AES aes = new AES(key, getKeySize(key)); AES aes = new AES(key, getKeySize(key));
byte[] H = aes.encryptBlock(new byte[16]); byte[] H = aes.encryptBlock(new byte[16]);
GHASH gh = new GHASH(H); GHASH gh = new GHASH(H);
@@ -82,7 +86,7 @@ public class AESGCM implements AESCipher {
if (!ToM(tag, expectedTag) && !flag) { if (!ToM(tag, expectedTag) && !flag) {
throw new XACryptoException("Tag does not match. USE flag \"-override\" to ignore this."); throw new XACryptoException("Tag does not match. USE flag \"-override\" to ignore this.");
} else if (!ToM(tag,expectedTag) && flag) { } else if (!ToM(tag,expectedTag) && flag) {
System.out.println("Continuing in insecure mode."); log.warn("Continuing in insecure mode.");
} }
return aes.encryptCTR(cip, J0); return aes.encryptCTR(cip, J0);