A few small code cleanups for cryptography
* Remove some unused cryptographic code * Add some notes about how Minecraft's cryptography choices have not quite survived the test of time
This commit is contained in:
@@ -26,6 +26,15 @@ Java_com_velocitypowered_natives_encryption_OpenSslCipherImpl_init(JNIEnv *env,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// But, you're saying, *why* are we using the key as the IV? After all, reusing the key as
|
||||||
|
// the IV defeats the entire point - we might as well just initialize it to all zeroes.
|
||||||
|
//
|
||||||
|
// You can blame Mojang. For the record, we also don't consider the Minecraft protocol
|
||||||
|
// encryption scheme to be secure, and it has reached the point where any serious cryptographic
|
||||||
|
// protocol needs a refresh. There are multiple obvious weaknesses, and this is far from the
|
||||||
|
// most serious.
|
||||||
|
//
|
||||||
|
// If you are using Minecraft in a security-sensitive application, *I don't know what to say.*
|
||||||
CCCryptorRef cryptor = NULL;
|
CCCryptorRef cryptor = NULL;
|
||||||
CCCryptorStatus result = CCCryptorCreateWithMode(encrypt ? kCCEncrypt : kCCDecrypt,
|
CCCryptorStatus result = CCCryptorCreateWithMode(encrypt ? kCCEncrypt : kCCDecrypt,
|
||||||
kCCModeCFB8,
|
kCCModeCFB8,
|
||||||
|
@@ -32,6 +32,15 @@ Java_com_velocitypowered_natives_encryption_OpenSslCipherImpl_init(JNIEnv *env,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// But, you're saying, *why* are we using the key as the IV? After all, reusing the key as
|
||||||
|
// the IV defeats the entire point - we might as well just initialize it to all zeroes.
|
||||||
|
//
|
||||||
|
// You can blame Mojang. For the record, we also don't consider the Minecraft protocol
|
||||||
|
// encryption scheme to be secure, and it has reached the point where any serious cryptographic
|
||||||
|
// protocol needs a refresh. There are multiple obvious weaknesses, and this is far from the
|
||||||
|
// most serious.
|
||||||
|
//
|
||||||
|
// If you are using Minecraft in a security-sensitive application, *I don't know what to say.*
|
||||||
int result = EVP_CipherInit(ctx, EVP_aes_128_cfb8(), (byte*) keyBytes, (byte*) keyBytes,
|
int result = EVP_CipherInit(ctx, EVP_aes_128_cfb8(), (byte*) keyBytes, (byte*) keyBytes,
|
||||||
encrypt);
|
encrypt);
|
||||||
if (result != 1) {
|
if (result != 1) {
|
||||||
|
@@ -48,6 +48,15 @@ public class JavaVelocityCipher implements VelocityCipher {
|
|||||||
|
|
||||||
private JavaVelocityCipher(boolean encrypt, SecretKey key) throws GeneralSecurityException {
|
private JavaVelocityCipher(boolean encrypt, SecretKey key) throws GeneralSecurityException {
|
||||||
this.cipher = Cipher.getInstance("AES/CFB8/NoPadding");
|
this.cipher = Cipher.getInstance("AES/CFB8/NoPadding");
|
||||||
|
// But, you're saying, *why* are we using the key as the IV? After all, reusing the key as
|
||||||
|
// the IV defeats the entire point - we might as well just initialize it to all zeroes.
|
||||||
|
//
|
||||||
|
// You can blame Mojang. For the record, we also don't consider the Minecraft protocol
|
||||||
|
// encryption scheme to be secure, and it has reached the point where any serious cryptographic
|
||||||
|
// protocol needs a refresh. There are multiple obvious weaknesses, and this is far from the
|
||||||
|
// most serious.
|
||||||
|
//
|
||||||
|
// If you are using Minecraft in a security-sensitive application, *I don't know what to say.*
|
||||||
this.cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key,
|
this.cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key,
|
||||||
new IvParameterSpec(key.getEncoded()));
|
new IvParameterSpec(key.getEncoded()));
|
||||||
}
|
}
|
||||||
|
@@ -236,6 +236,15 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
|
|
||||||
registerTranslations();
|
registerTranslations();
|
||||||
|
|
||||||
|
// Yes, you're reading that correctly. We're generating a 1024-bit RSA keypair. Sounds
|
||||||
|
// dangerous, right? We're well within the realm of factoring such a key...
|
||||||
|
//
|
||||||
|
// You can blame Mojang. For the record, we also don't consider the Minecraft protocol
|
||||||
|
// encryption scheme to be secure, and it has reached the point where any serious cryptographic
|
||||||
|
// protocol needs a refresh. There are multiple obvious weaknesses, and this is far from the
|
||||||
|
// most serious.
|
||||||
|
//
|
||||||
|
// If you are using Minecraft in a security-sensitive application, *I don't know what to say.*
|
||||||
serverKeyPair = EncryptionUtils.createRsaKeyPair(1024);
|
serverKeyPair = EncryptionUtils.createRsaKeyPair(1024);
|
||||||
|
|
||||||
cm.logChannelInformation();
|
cm.logChannelInformation();
|
||||||
|
@@ -23,8 +23,6 @@ import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
|||||||
import it.unimi.dsi.fastutil.Pair;
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
@@ -111,42 +109,6 @@ public enum EncryptionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a signature for input data.
|
|
||||||
*
|
|
||||||
* @param algorithm the signature algorithm
|
|
||||||
* @param base the private key to sign with
|
|
||||||
* @param toSign the byte array(s) of data to sign
|
|
||||||
* @return the generated signature
|
|
||||||
*/
|
|
||||||
public static byte[] generateSignature(String algorithm, PrivateKey base, byte[]... toSign) {
|
|
||||||
Preconditions.checkArgument(toSign.length > 0);
|
|
||||||
try {
|
|
||||||
Signature construct = Signature.getInstance(algorithm);
|
|
||||||
construct.initSign(base);
|
|
||||||
for (byte[] bytes : toSign) {
|
|
||||||
construct.update(bytes);
|
|
||||||
}
|
|
||||||
return construct.sign();
|
|
||||||
} catch (GeneralSecurityException e) {
|
|
||||||
throw new IllegalArgumentException("Invalid signature parameters");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes a long array as Big-endian byte array.
|
|
||||||
*
|
|
||||||
* @param bits the long (array) of numbers to encode
|
|
||||||
* @return the encoded bytes
|
|
||||||
*/
|
|
||||||
public static byte[] longToBigEndianByteArray(long... bits) {
|
|
||||||
ByteBuffer ret = ByteBuffer.allocate(8 * bits.length).order(ByteOrder.BIG_ENDIAN);
|
|
||||||
for (long put : bits) {
|
|
||||||
ret.putLong(put);
|
|
||||||
}
|
|
||||||
return ret.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String encodeUrlEncoded(byte[] data) {
|
public static String encodeUrlEncoded(byte[] data) {
|
||||||
return MIME_SPECIAL_ENCODER.encodeToString(data);
|
return MIME_SPECIAL_ENCODER.encodeToString(data);
|
||||||
}
|
}
|
||||||
@@ -155,22 +117,6 @@ public enum EncryptionUtils {
|
|||||||
return Base64.getMimeDecoder().decode(toParse);
|
return Base64.getMimeDecoder().decode(toParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a cer-encoded RSA key into its key bytes.
|
|
||||||
*
|
|
||||||
* @param toParse the cer-encoded key String
|
|
||||||
* @param descriptors the type of key
|
|
||||||
* @return the parsed key bytes
|
|
||||||
*/
|
|
||||||
public static byte[] parsePemEncoded(String toParse, Pair<String, String> descriptors) {
|
|
||||||
int startIdx = toParse.indexOf(descriptors.first());
|
|
||||||
Preconditions.checkArgument(startIdx >= 0);
|
|
||||||
int firstLen = descriptors.first().length();
|
|
||||||
int endIdx = toParse.indexOf(descriptors.second(), firstLen + startIdx) + 1;
|
|
||||||
Preconditions.checkArgument(endIdx > 0);
|
|
||||||
return decodeUrlEncoded(toParse.substring(startIdx + firstLen, endIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes an RSA key as String cer format.
|
* Encodes an RSA key as String cer format.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user