Netty StreamCorruptedException After Keyexchange - java

I am trying to build an encrypted Netty connection using AES.
RSA is helping me to transmit the AES key and the iv.
Server and client have the same key and iv after the exchange. I am creating ciphers to
actually de- and encrypt stuff with it.
When I am running the server on my pc in eclipse with the Cp1252 encoding it's working fine.
As soon as I change the encoding to UTF-8 (encoding my client is written in) or run the server on my Linux system its not working anymore.
I saw that i can get the iv from the cipher with cipher.getIV(); unfortunately they're not the same
so that might be the problem.
Exception (client)
Server output
As you can see the AES key and IV are the same.
This is how I'm generating the Cipher
public static Cipher generateCipher(byte[] secret, int mode, byte[] iv) {
KeySpec spec = new PBEKeySpec(new String(secret).toCharArray(), iv, 65536, 128);
try {
byte[] key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec).getEncoded();
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
IvParameterSpec parameterSpec = new IvParameterSpec(secretKey.getEncoded());
cipher.init(mode, secretKey, parameterSpec);
return cipher;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
This is how I print the Strings
byte[] aesKey = CryptionUtils.decryptRSA(packet.getKey(), rsaKeys.getPrivate());
byte[] iv = CryptionUtils.decryptRSA(packet.getIv(), rsaKeys.getPrivate());
if (iv.length != 12 || aesKey.length != 16) {
server.sendPacket(ip, new KickPacket(EnumKickPacket.INVALID_AES_INFO.ordinal()));
server.disconnectClient(ip, EnumKickPacket.INVALID_AES_INFO.name());
}
Cipher decryptCipher = CryptionUtils.generateCipher(aesKey, Cipher.DECRYPT_MODE, iv);
Cipher encryptCipher = CryptionUtils.generateCipher(aesKey, Cipher.ENCRYPT_MODE, iv);
System.out.println("IV: " + Base64.getEncoder().encodeToString(iv));
System.out.println("AESKey: " + Base64.getEncoder().encodeToString(aesKey));
System.out.println("DecryptCipher: " + Base64.getEncoder().encodeToString(decryptCipher.getIV()));
System.out.println("EncryptCipher: " + Base64.getEncoder().encodeToString(encryptCipher.getIV()));

new String(secret, Charset.forName("UTF-8")
Fixed the issue.

Related

Decrypting a message encrypted using a hashed key

I have a problem where I need to decrypt a message which was encrypted using AES=256. I am already provided with a key and vector. I have to hash the provided key using SHA-256 and then use this hash to encrypt a message. The decryption code runs fine but the result is not the original String.
Result: ?m?>? ???????z?p???>??<3? (the exact text is different, but after copying and pasting it, it is different).
My code below:
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest("someKey".getBytes(ENCODING_UTF8));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("somevector".getBytes(ENCODING_UTF8));
SecretKeySpec skeySpec = new SecretKeySpec(hashBytes, AES);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] cipherText = cipher.doFinal(plainText.getBytes(ENCODING_UTF8));
encrypted = EACECryptoUtils.base64Encode(cipherText);
Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_TYPE);
IvParameterSpec decryptIV = new IvParameterSpec("somevector".getBytes(ENCODING_UTF8));
SecretKeySpec decryptSkeySpec = new SecretKeySpec(hashBytes, AES);
decryptCipher.init(Cipher.DECRYPT_MODE, decryptSkeySpec, decryptIV);
byte[] original = cipher.doFinal(EACECryptoUtils.base64Decode(encrypted));
decrypted = new String(original);
} catch (Exception e) {
log.error(new LogRecord(FUNCTION_NAME + "Exception while encrypting the data", e));
throw e;
}
}
byte[] original = cipher.doFinal(EACECryptoUtils.
I believe you should use decryptCipher instead of cipher

Java equivalent of Ruby AES CBC Decryption

The below ruby code works
require 'openssl'
require "base64"
cipher = OpenSSL::Cipher::AES256.new(:CBC)
cipher.decrypt
cipher.key = Base64.strict_decode64("LLkRRMSAlD16lrfbRLdIELdj0U1+Uiap0ihQrRz7HSQ=")
cipher.iv = Base64.strict_decode64("A23OFOSvsC4UyejA227d8g==")
crypt = cipher.update(Base64.strict_decode64("D/e0UjAwBF+d8aVqZ0FpXA=="))
crypt << cipher.final
puts crypt # prints Test123
but trying to do the same in java with same key/iv/cipher but it doesn't return 'Test123'
Security.addProvider(new BouncyCastleProvider());
byte[] key = Base64.getDecoder().decode("LLkRRMSAlD16lrfbRLdIELdj0U1+Uiap0ihQrRz7HSQ=");
byte[] iv = Base64.getDecoder().decode("A23OFOSvsC4UyejA227d8g==");
byte[] input = Base64.getDecoder().decode("D/e0UjAwBF+d8aVqZ0FpXA==");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
byte[] output = cipher.doFinal(input);
System.out.println("[" + new String(output) + "] - "+output.length);
For simplicity key and iv are hardcoded
You're telling it to encrypt, not to decrypt. The corrected line of code is
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
Furthermore, if you want to use BouncyCastle for this, use
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", BouncyCastleProvider.PROVIDER_NAME);
or make BouncyCastle the default:
Security.insertProviderAt(new BouncyCastleProvider(), 1);

decrypting aes-gcm encrypted with java using openssl

I have the following code in Java:
public static void deriveKeyAndIV(String password)
throws Exception
{
SecureRandom random = new SecureRandom();
if (salt == null)
{
salt = new byte[HASH_BYTE_SIZE / 8]; // use salt size at least as long as hash
random.nextBytes(salt);
}
if (ivBytes == null)
{
ivBytes = new byte[HASH_BYTE_SIZE / 8];
random.nextBytes(ivBytes);
}
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
keyBytes = skf.generateSecret(spec).getEncoded();
}
public static byte[] encrypt(byte[] message)
throws Exception
{
// wrap key data in Key/IV specs to pass to cipher
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
//IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
// create the cipher with the algorithm you choose
// see javadoc for Cipher class for more info, e.g.
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
GCMParameterSpec gps = new GCMParameterSpec(128, ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, key, gps);
byte[] encrypted = new byte[cipher.getOutputSize(message.length)];
int enc_len = cipher.update(message, 0, message.length, encrypted, 0);
enc_len += cipher.doFinal(encrypted, enc_len);
return encrypted;
}
public static byte[] decrypt(byte[] cipher_text)
throws Exception
{
// wrap key data in Key/IV specs to pass to cipher
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
// create the cipher with the algorithm you choose
// see javadoc for Cipher class for more info, e.g.
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
GCMParameterSpec gps = new GCMParameterSpec(128, ivBytes);
cipher.init(Cipher.DECRYPT_MODE, key, gps);
byte[] decrypted = new byte[cipher.getOutputSize(cipher_text.length)];
int dec_len = cipher.update(cipher_text, 0, cipher_text.length, decrypted, 0);
dec_len += cipher.doFinal(decrypted, dec_len);
return decrypted;
}
public static void main(String[] args) {
String pass = "hello";
try {
deriveKeyAndIV(pass);
byte[] tmp = encrypt("world!".getBytes());
System.out.println(new String(Base64.getEncoder().encode(tmp)));
System.out.println(new String(tmp));
System.out.println("encrypted:\t" + bytesToHex(tmp));
System.out.println("key:\t" + bytesToHex(keyBytes));
System.out.println("iv:\t" + bytesToHex(ivBytes));
tmp = decrypt(tmp);
System.out.println("decrypted:\t" + bytesToHex(tmp));
} catch (Exception e) {
e.printStackTrace();
}
}
Sample output:
5xwfm037nXfGS06V5OKgW/oo6WDuow==
��M��w�KN���[�(�`�
encrypted: E71C1F9B4DFB9D77C64B4E95E4E2A05BFA28E960EEA3
key: 6D525D38BFF7F70AD25205E97368C197
iv: 060374643557ED8E2F6A215F1B6DBD0E
decrypted: 776F726C6421
I copied the Base64 output into a file (test-in), and tried decrypting it using the following command:
openssl enc -d -base64 -id-aes128-GCM -K 6D525D38BFF7F70AD25205E97368C197 -in ~/Desktop/test-in -out ~/Desktop/test-out -iv 060374643557ED8E2F6A215F1B6DBD0E
I got a bad decrypt error message (exit code: 1). trying different modes (id-aes192-GCM and id-aes256-GCM) resulted the same.
What I'm doing wrong?
I copied the Base64 output into a file (test-in), and tried decrypting it using the following command ...
Authenticated encryption modes do not work from the command line tools. From the openssl enc man page:
The enc program does not support authenticated encryption modes like
CCM and GCM. The utility does not store or retrieve the authentication
tag.
I know the documentation was recently updated (circa May or June 2014) with the statement above. The mailing list message that triggered it was v1.0.1g command line gcm error.
I don't know if newer versions of the tools (like openssl enc in 1.0.2 or 1.1.0) provide a meaningful error message, or if you just get bad decrypt.
What I'm doing wrong?
Nothing.
it may be a bug, see: http://openssl.6102.n7.nabble.com/1-1-0-dev-AES-GCM-on-command-line-quot-bad-decrypt-quot-but-seems-to-work-td49979.html, even this does not entirely work:
KEY=6D525D38BFF7F70AD25205E97368C197
IV=060374643557ED8E2F6A215F1B6DBD0E
echo "world!" | openssl enc -id-aes128-GCM -K $KEY -iv $IV | openssl enc -d -id-aes128-GCM -K $KEY -iv $IV
world!
bad decrypt

Java multi-level aes de/encrypting fails

I have been tasked with decrypting a file in Java that has been encrypted using the following criteria:
Encrypting:
`
byte[] masterKey;
if (Base64.decode(config.getProperty("encrMasterKey")) != null) {
masterKey=aes.decrypt(Base64.decode(config.getProperty("encrMasterKey")),"password");
} else {
masterKey = aes.keyGeneration();
byte[] encrMasterKey = aes.encrypt(masterKey, keyderivation("password"));
writeToConfigFile("encrMasterKey", Base64.encode(encrMasterKey));
}
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(masterKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] cypherText = aes.encrypt(myJSONString,masterKey);'
What works:
i can encrypt/decrypt with AES, both with byte[] and from password derivated keys(keyderivation("password"))
i can save and load correctly from the config file. In fact i tested and the generated Base64encoded( masterKey )is the same as the Base64.encode(aes.decrypt(Base64.decode(config.getProperty("encrMasterKey")),"password")))
What doesnt:
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(masterKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
At cipher.init java throws an illegal key or default parameter error.
I would really appreciate a hint on this one, keeps bugging me for days now and i cant seem to fix it...
Best wishes

AES/CBC/PKCS5Padding Java Encrypting Error - javax.crypto.BadPaddingException: Given final block not properly padded

I'm trying to do encryption-decryption of a String using AES/CBC/PKCS5Padding
I'm getting this Exception: javax.crypto.BadPaddingException: Given final block not properly padded
the string i'm trying to encrypt: ftp.clarapoint.com
Here is my encryption code:
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] data = cipher.doFinal(stringDec.getBytes());
byte[] iv = cipher.getIV();
I'm transfering the decryption method the following: aesKey, data and iv
the decryption code:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AlgorithmParameters.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));
byte[] decrypted = cipher.doFinal(data);
Thanks!
You are not transfering either the key or the cipher text correctly, as this code does run:
private static void testCode() {
try {
String stringDec = "Hi there";
SecretKey aesKey = new SecretKeySpec(new byte[16], "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
// no encoding given, don't use getBytes() without a Charset.forName("UTF-8")
byte[] data = cipher.doFinal(stringDec.getBytes());
byte[] iv = cipher.getIV();
// doesn't do anything
AlgorithmParameters.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));
byte[] decrypted = cipher.doFinal(data);
System.out.println(new String(decrypted));
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
}

Categories