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
Advertisement
Answer
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