Not sure if this helps, since the SAML2 Assertion XML is somewhat different, but here it is anyway:
1. generate a public/private key pair for encryption use
2. went to https://www.samltool.com/encrypt.php and generated an encrypted SAML2 Assertion, using RSA_OAEP_MGF1P for "Encrypted Method for key", "AES128_CBC" for "Encrypted Method for the data" and the public cert from step 1. Saved the output to a file, encrypted_assertion.xml
3. My private key was in PKCS#8 format, so generated a PKCS#1 version of it using openssl rsa -in myenc.key -out myenc1.key (the Perl code I use only accepts PKCS#1 format)
4. from the SAML2 spec I see that the first 128bits of the encrypted data is actually the IV, https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#aes128-cbc (section 5.2.2)
5. using the code from http://stuff-things.net/2007/05/02/encrypting-sensitive-data-with-perl/ to retrieve the encrypted key from the XML (hence the PKCS#1 version of the private key in step 3, to use in the CBC decoding of the data, I came up with the following code (after much trial and error with the Crypt::CBC parameters):
use strict;
use warnings;
use Crypt::OpenSSL::RSA;
use XML::Simple;
use File::Slurp;
use MIME::Base64 qw(decode_base64);
use Convert::PEM;
use Crypt::OpenSSL::AES;
use Crypt::CBC;
my $xml = read_file("encrypted_assertion.xml");
my $pem = Convert::PEM->new( Name => 'RSA
+ PRIVATE KEY',
ASN => qq(
RSAPrivateKey SEQUENCE {
version INTEGER,
n INTEGER,
e INTEGER,
d INTEGER,
p INTEGER,
q INTEGER,
dp INTEGER,
dq INTEGER,
iqmp INTEGER
}
));
my $pemkey = $pem->read(Filename => "myenc1.key");
my $key = Crypt::OpenSSL::RSA->new_private_key($pem->encode(Content =>
+ $pemkey));
my $xml_data = XMLin($xml);
my $CipherKey = decode_base64($xml_data->{"dsig:KeyInfo"}{"xenc:Encryp
+tedKey"}{"xenc:CipherData"}{"xenc:CipherValue"});
my $aeskey = $key->decrypt($CipherKey);
my $CipherData = decode_base64($xml_data->{"xenc:CipherData"}{"xenc:Ci
+pherValue"});
my $cipher = Crypt::CBC->new(-key => $aeskey,
-cipher => "Crypt::OpenSSL::AES",
-iv => substr($CipherData,0,16),
-literal_key => 1,
-header => 'none',
-keysize => length($aeskey));
print $cipher->decrypt ( substr($CipherData ,16) );
There are some junk characters at the end of the output, I guess it's some padding.
This takes 0.455s to run.
Using perl -e 'print `xmlsec1 --decrypt --privkey-pem myenc.key encrypted_assertion.xml`' takes 0.015s, and outputs no junk.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.