Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Re: Perl and Encrypted SAML Token

by rdfield (Priest)
on Jun 12, 2017 at 13:01 UTC ( #1192577=note: print w/replies, xml ) Need Help??

in reply to Perl and Encrypted SAML Token

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 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, (section 5.2.2)

5. using the code from 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.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1192577]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2021-03-04 22:40 GMT
Find Nodes?
    Voting Booth?
    My favorite kind of desktop background is:

    Results (108 votes). Check out past polls.