Skip to content

Instantly share code, notes, and snippets.

@yaronn
Last active January 24, 2024 00:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yaronn/6765830 to your computer and use it in GitHub Desktop.
Save yaronn/6765830 to your computer and use it in GitHub Desktop.
Decrypt SOAP Body encrypted with X.509 certificate with WS-Security (C#).
//decrypt the encryptedKey to get the session key:
//==================================================
string wrappingKey = "put here the value base64 CipherValue under the encryptedKey element";
X509Certificate2 serverCert = new X509Certificate2(File.ReadAllBytes(@"c:\temp\xws-security-server.p12"), "changeit");
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)serverCert.PrivateKey;
var enckey = rsa.Decrypt(Convert.FromBase64String(wrappingKey), true);
return enckey;
//decrypt the soap body using the session key (aes128):
//=====================================================
internal static byte[] ExtractIVAndDecrypt(SymmetricAlgorithm algorithm, byte[] cipherText, int offset, int count)
{
byte[] buffer2;
if (cipherText == null)
{
throw new Exception();
}
if ((count < 0) || (count > cipherText.Length))
{
throw new Exception();
}
if ((offset < 0) || (offset > (cipherText.Length - count)))
{
throw new Exception();
}
int num = algorithm.BlockSize / 8;
byte[] dst = new byte[num];
Buffer.BlockCopy(cipherText, offset, dst, 0, dst.Length);
algorithm.Padding = PaddingMode.ISO10126;
algorithm.Mode = CipherMode.CBC;
try
{
using (ICryptoTransform transform = algorithm.CreateDecryptor(algorithm.Key, dst))
{
buffer2 = transform.TransformFinalBlock(cipherText, offset + dst.Length, count - dst.Length);
}
}
catch (CryptographicException exception)
{
throw new Exception();
}
return buffer2;
}
//the IV is the first 16 byes (in our case) of the encrypted cipher (not key)
private byte[] GetIV( byte[] cypher)
{
byte[] IV = new byte[16];
Array.Copy(cypher, IV, 16);
return IV;
}
//note the cipher contains the iv inside it but we do not remove it since the methods expect to get the cipher with iv and ic separately
byte[] cypher = Convert.FromBase64String("put here the base64 encrypted cipherValue under the encrypted body");
byte[] key =this.key; //we are assumed to know the key. for example we decrypted it using the method above.
byte[] iv = GetIV(cypher);
var AesManagedAlg = new AesCryptoServiceProvider();
AesManagedAlg.KeySize = 128;
AesManagedAlg.Key = key;
AesManagedAlg.IV = iv;
var body = ExtractIVAndDecrypt(AesManagedAlg, cypher, 0, cypher.Length);
System.Out.Print("decrypted body is: " + UTF8Encoding.UTF8.GetString(body));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment