Skip to content
Advertisement

How to decrypt EncryptedAssertion manually

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

EncryptedAssertion

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

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement