Last active
January 24, 2024 00:19
-
-
Save yaronn/6765830 to your computer and use it in GitHub Desktop.
Decrypt SOAP Body encrypted with X.509 certificate with WS-Security (C#).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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