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
Related
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.
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
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);
i have a AESkey which encrypted by a public key, and later decrypted by a private key
Cipher cipher = Cipher.getInstance("RSA");
PrivateKey privateKey = keyPair.getPrivate();
// decrypt the ciphertext using the private key
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedText = cipher.doFinal(theBytes);
theBytes is a byte[] containing a encrypted AESkey, the question is how to convert the decryptedText back to the AESkey?
I believe you're receiving an RSA-encrypted AES key along with some AES-encrypted data, and you still need to perform the second of 2 encryptions. Right?
So, anyway, you can load a key from the byte array.
SecretKeySpec secretKeySpec = new SecretKeySpec(decryptedText, "AES");
Subsequently you'd do something like this, to decrypt the AES-encrypted data, 'encrypted':
Cipher cipherAes = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipherAes.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = cipherAes.doFinal(encrypted);
String decryptedString = new String(decryptedBytes);
The /CBC/PKCS7Padding specification may vary, depending on how it was specified during encryption.
Hope this helps.
I've been stuck on a bug in my code, it will not let me decrypt properly!
I am only passing eight bytes of data to dataBytes and I am passing
a 24 byte key to keyBytes.
I am trying to return the decrypted data as an array of bytes.
I keep getting the bad padding exception.
Thanks!
Here is the code snippet:
private static byte[] DESEdeDecrypt(byte[] keyBytes, byte[] dataBytes){
byte[] decryptedData = null;
try{
DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes, 0);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedData = cipher.doFinal(dataBytes);
}
catch(Exception e){System.out.println(e);}
return decryptedData;
You must use the same padding to decrypt as you did to encrypt. It is better to set it explicitly rather than to rely on defaults. Best also to specify the mode at both ends as well:
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
DESede is slow and obsolescent. You shouldn't use it except for compatibility with old code. For new work it is better to use AES.