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
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 want to decrypt the EncryptedAssertion. I tried with OpenSaml Decrypter but its not working for me.I am getting Failed to decrypt EncryptedData
I have already ask that question - EncryptedAssertion Decryption failing
While I am waiting for any solution I am trying to decrypt it manually. Its a Hybrid encryption
I tried below code
CipherValue cv = encryptedAssertion.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0).getCipherData().getCipherValue();
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
String decryptedValue = new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(cvalue)));
I am not sure if I am on the right path, but above decryptedValue is the decryption key for my Encrypted Data.This decryptedValue is not in readable format. Not sure what to do next.
getPrivateKey method
public PrivateKey getPrivateKey(){
Key key = null;
PrivateKey privateKey = null;
try {
KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");
ks.load(new FileInputStream("prvkey.pfx"),"".toCharArray());
Enumeration<String> aliases = ks.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
key = ks.getKey(alias, "".toCharArray());
privateKey = (PrivateKey)key;
}
} catch (Exception e) {
e.printStackTrace();
}
}
Based on the suggestion I coded like below. Not sure if I am doing it correct also I am getting errors
`CipherValue cv = encryptedAssertion.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0).getCipherData().getCipherValue();
String cvalue = cv.getValue();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, getPrivateKey());
Key decryptionKey = cipher.unwrap(DatatypeConverter.parseBase64Binary(cvalue), "RSA/ECB/PKCS1Padding", Cipher.SECRET_KEY);
CipherValue cdata = encryptedAssertion.getEncryptedData().getCipherData().getCipherValue();
String cdataValue = cdata.getValue();
byte[] iv = new byte[256 / 16];
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(), "AES");
cipher2.init(Cipher.DECRYPT_MODE, spec, ivParamSpec );
String decryptedValue = new String(cipher2.doFinal(DatatypeConverter.parseBase64Binary(cdataValue)));`
Error -
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2121)
UPDATE ::
hope I am doing it correctly based on the comments.
byte[] iv = new byte[256/16];
iv = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue), 0, 16);
byte[] cipherBlock = Arrays.copyOfRange(DatatypeConverter.parseBase64Binary(cdataValue), 16, DatatypeConverter.parseBase64Binary(cdataValue).length);
IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec spec = new SecretKeySpec(decryptionKey.getEncoded(), "AES");
cipher2.init(Cipher.DECRYPT_MODE, spec, ivParamSpec );
String decryptedValue = new String(cipher2.doFinal(cipherBlock)); // Same error - Given final block not properly padded
I won't provide you a complete answer but I hope to get you on the right track
You should not just simply decrypt the calue with the private key.
First decrypt the KeyInfo value (unwrap the aes key) using RSA/ECB/PKCS1Padding (according to the provided saml snippet)
It should give you a 256 bit (32 bytes) random key used to encrypt data itself
then use the AES key to decrypt the data . Please note that first bytes (128 bit / 16 bytes, aes block size) is used as IV.
further reading
https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#sec-Processing-Encryption
https://gusto77.wordpress.com/2017/10/30/encryption-reference-project/
public static byte[] decrypt(byte[] cryptoBytes, byte[] aesSymKey)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
// https://github.com/onelogin/java-saml/issues/23
String cipherMethod = "AES/CBC/ISO10126Padding"; // This should be derived from Cryptic Saml
AlgorithmParameterSpec iv = new IvParameterSpec(cryptoBytes, 0, 16);
// Strip off the the first 16 bytes because those are the IV
byte[] cipherBlock = Arrays.copyOfRange(cryptoBytes,16, cryptoBytes.length);
// Create a secret key based on symKey
SecretKeySpec secretSauce = new SecretKeySpec(aesSymKey, "AES");
// Now we have all the ingredients to decrypt
Cipher cipher = Cipher.getInstance(cipherMethod);
cipher.init(Cipher.DECRYPT_MODE, secretSauce, iv);
// Do the decryption
byte[] decrypedBytes = cipher.doFinal(cipherBlock);
return decrypedBytes;
}
ISO10126Padding should work....
I want to encrypt an arbitrary text with RSA, but as I read, RSA dont allow to long texts, so firsts, I need to encrypt with AES-256 (for example), then encrypt the AES key with RSA public, add the encrypted text(with AES), and send the message.
At this moment, I'm doing the AES enc-dec. But I'm doing something wrong because is not decrypting the message properly:
First I generate the AES Key:
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(KEY_SIZE_AES);
this.secretKey_AES = keyGenerator.generateKey();
return this.secretKey_AES;
then I encrypt the message:
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey_AES);
byte[] encrypted = cipher.doFinal(message.getBytes("UTF-8"));
String encryptedMessage = Base64.encodeToString(encrypted, Base64.DEFAULT);
return encryptedMessage;
and finally I decrypt it:
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey_AES);
byte[] decrypted = cipher.doFinal(Base64.decode(message,Base64.DEFAULT));
String decryptedMessage = new String(Base64.encode(decrypted, Base64.DEFAULT));
return decryptedMessage;
But the decrypted text is not the same as the original. I'm missing somthing?
Or I forget some step?
Example:
Your code is working properly, but you are encoding the result in BASE64. ("Elias" is "RWxpYXM" in base64). Just change
String decryptedMessage = new String(Base64.encode(decrypted, Base64.DEFAULT));
with
String decryptedMessage = new String(decrypted, "UTF-8");
Note that this method will only work for text strings
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'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);
}
}