openssl compatible key and IV calculation

Discussion in 'Perl Misc' started by Markus Steinborn, Aug 13, 2013.

  1. Hello,

    I'd like to compute the initialisation vector and the key for decrypting
    ciphertexts. The operation I'd like to do can be done with openssl by
    the following command:

    openssl enc -a -aes-256-cbc -pass pass:"Secret Passphrase" -base64 -P -S
    ab001d77079ba218

    Obviously "Secret passphrase" is the passphrase and "ab001d77079ba218"
    is the salt - we'll assume that both are known.

    The goal is to compute the initialisation vector (IV) and the key.


    How to do that in perl?

    The openssl man-pages and google did not help me.




    Thanks

    Markus Steinborn
    Markus Steinborn, Aug 13, 2013
    #1
    1. Advertising

  2. Markus Steinborn

    J. Gleixner Guest

    On 08/13/13 11:21, Markus Steinborn wrote:
    > Hello,
    >
    > I'd like to compute the initialisation vector and the key for decrypting
    > ciphertexts. The operation I'd like to do can be done with openssl by
    > the following command:
    >
    > openssl enc -a -aes-256-cbc -pass pass:"Secret Passphrase" -base64 -P -S
    > ab001d77079ba218
    >
    > Obviously "Secret passphrase" is the passphrase and "ab001d77079ba218"
    > is the salt - we'll assume that both are known.
    >
    > The goal is to compute the initialisation vector (IV) and the key.
    >
    >
    > How to do that in perl?
    >
    > The openssl man-pages and google did not help me.


    openssl is a command/executable and the above produces output, so it's
    not anything special or different from many other commands. If you
    want to execute the command, capture the output, and do something
    with it...

    use strict;
    use warnings;

    my $str = `/usr/bin/openssl enc -a -aes-256-cbc -pass pass:"Secret
    Passphrase"-base64 -P -S ab001d77079ba218`;

    my %fields = $str =~ / (\S+) \s* = \s* (\S+) /xg;

    use Data::Dumper;
    print Dumper( \%fields );

    $VAR1 = {
    'salt' => 'AB001D77079BA218',
    'iv' => 'B99974A9FF1F39AF888BC378015C37D1',
    'key' =>
    'A4430C9C6AD9B88836B7277193CC21C56E5503F6F0DBF3E777A31BE7D42765F8'
    };
    J. Gleixner, Aug 13, 2013
    #2
    1. Advertising

  3. Hi Gleixner,

    thanks for your answer.

    J. Gleixner schrieb:
    >
    > my $str = `/usr/bin/openssl enc -a -aes-256-cbc -pass pass:"Secret
    > Passphrase"-base64 -P -S ab001d77079ba218`;


    Not bad... I'm developinig under Linux, but the hard encoded path might
    be a portability problem, especcially on windows (ActiveState Perl 5.16
    with Crypt::CBC and Crypt::OpenSSL::AES).

    Perhaps there is a trick to use either the OpenSSL system library (on
    linux/Unix) or the openSSL library ActiveState Perl uses (on windows).

    But anyway: An enviromnent variable poiting to the openssl binary might
    help out of this situation - if we do not find anything better.

    I just thought that there might be a perl solution like
    Crypt::OpenSSL::AES for the encryption/decryption.


    Greetings from Germany

    Markus
    Markus Steinborn, Aug 13, 2013
    #3
  4. Markus Steinborn <> wrote:
    >I'd like to compute the initialisation vector and the key for decrypting
    >ciphertexts. The operation I'd like to do can be done with openssl by
    >the following command:
    >
    >openssl enc -a -aes-256-cbc -pass pass:"Secret Passphrase" -base64 -P -S
    >ab001d77079ba218
    >
    >Obviously "Secret passphrase" is the passphrase and "ab001d77079ba218"
    >is the salt - we'll assume that both are known.
    >
    >The goal is to compute the initialisation vector (IV) and the key.
    >How to do that in perl?


    It looks like you got a working solution already. Is there a specific
    reason why you can't just call 'openssl' from you Perl script?

    jue
    Jürgen Exner, Aug 13, 2013
    #4
  5. Jürgen Exner wrote:

    > It looks like you got a working solution already. Is there a specific
    > reason why you can't just call 'openssl' from you Perl script?


    Well, I've a weak one: I'd prefer to get rid on openssl dependencies...
    There exist Crypt::Rijndael (which might need some fixing). But it's
    always nice to have a working fallback - it might happen that I cannot
    get rid of OpenSSL.

    The problem with openssl is: It is not installed on an average windows
    machine.



    Markus
    Markus Steinborn, Aug 14, 2013
    #5
  6. Hi Ben,

    Ben Morrow schrieb:

    > Well, have you tried using those two together? I can't see any reason it
    > shouldn't work. You could also try Crypt::Cipher::AES, which has its own
    > AES implementation and doesn't depend on OpenSSL.


    thanks, that's exactly I'm looking for - noticing that it does not solf
    key and IV calculation without openssl, but decrypting without openssl.


    Markus
    Markus Steinborn, Aug 14, 2013
    #6
  7. Ben Morrow schrieb:
    >
    > Quoth Markus Steinborn <>:
    >> with Crypt::CBC and Crypt::OpenSSL::AES).

    >
    > Well, have you tried using those two together? I can't see any reason it
    > shouldn't work.


    They work fiine tohether under Linux (Windows not tested yet) - but
    offer no methood for an openssl compatible key and IV calculation.


    Markus
    Markus Steinborn, Aug 14, 2013
    #7
  8. Hi Ben,

    Ben Morrow schrieb:

    > Oh, sorry, I missed the significance of the -P option.
    >
    > Looking through the source of Crypt::CBC, the key/IV calculation doesn't
    > depend on either the cipher or the plaintext, and this gives me the same
    > results as openssl(1):


    Wow, you've got it - that is what I've been looking for... and a handy
    source code which clearly documents how these values are calculated --
    perfect.

    I'm testing it in the next few days.


    Thanks

    Markus
    Markus Steinborn, Aug 14, 2013
    #8
  9. On 8/14/2013 5:29 PM, Ben Morrow wrote:
    >
    > Quoth Markus Steinborn <>:
    >> Ben Morrow schrieb:
    >>
    >>> Oh, sorry, I missed the significance of the -P option.
    >>>
    >>> Looking through the source of Crypt::CBC, the key/IV calculation doesn't
    >>> depend on either the cipher or the plaintext, and this gives me the same
    >>> results as openssl(1):

    >>
    >> Wow, you've got it - that is what I've been looking for... and a handy
    >> source code which clearly documents how these values are calculated --
    >> perfect.

    >
    > Well, all I did was pull the code out of Crypt::CBC.
    >
    > I don't know where this function is specified, but I have to say I'm a
    > little worried about the unconditional use of MD5. In the Kerberos
    > world, which I'm more familiar with, this function is called
    > 'string2key' and is considered cryptographically significant. Modern
    > Kerberos enctypes, in particular the AES enctypes, use a function from
    > PKCS#5, which uses SHA-1 rather than MD5 and performs many iterations to
    > increase the cost of a dictionary attack.
    >
    > If you're using this one-iteration-of-MD5 function for encrypting
    > anything important, it's probably worth being rather careful to use very
    > strong passphrases.


    openssl will handle SHA so perhaps a very small patch to Crypt::CBC and
    the script itself to replace Digest::MD5::md5 with Digest::SHA::sha1
    might be another option...



    --
    Charles DeRykus
    Charles DeRykus, Aug 15, 2013
    #9
  10. Ben Morrow <> writes:

    [...]

    > In the Kerberos world, which I'm more familiar with, this function
    > is called 'string2key' and is considered cryptographically
    > significant. Modern Kerberos enctypes, in particular the AES
    > enctypes, use a function from PKCS#5, which uses SHA-1 rather than
    > MD5 and performs many iterations to increase the cost of a
    > dictionary attack.


    Ehh ... there is no way to do 'a dictionary attack' against Kerberos
    because the keys derived from user passphrases are supposed to be kept
    secret. There also wouldn't be any point in performing such a
    dictionary attack because the key derived from such a passphrase is
    what is actually used for authentication: Someone who knows that
    doesn't need to know the passphrase.

    > If you're using this one-iteration-of-MD5 function for encrypting
    > anything important,


    JFTR: The algortihm you posted does 3 rounds of MD5, not one.
    Rainer Weikusat, Aug 15, 2013
    #10
  11. Markus Steinborn <> writes:
    > Ben Morrow schrieb:
    >
    >> Oh, sorry, I missed the significance of the -P option.
    >>
    >> Looking through the source of Crypt::CBC, the key/IV calculation doesn't
    >> depend on either the cipher or the plaintext, and this gives me the same
    >> results as openssl(1):

    >
    > Wow, you've got it - that is what I've been looking for... and a
    > handy source code which clearly documents how these values are
    > calculated -- perfect.


    Except one minor nit: For algorithms without (known) 'classes of weak
    keys' (such as AES), you can as well just use (cryptographically
    strong) random numbers (aka 'a sufficient quantity of randomly
    generated bytes').
    Rainer Weikusat, Aug 15, 2013
    #11
  12. Markus Steinborn <> writes:
    > I'd like to compute the initialisation vector and the key for
    > decrypting ciphertexts. The operation I'd like to do can be done with
    > openssl by the following command:
    >
    > openssl enc -a -aes-256-cbc -pass pass:"Secret Passphrase" -base64 -P
    > -S
    > ab001d77079ba218
    >
    > Obviously "Secret passphrase" is the passphrase and "ab001d77079ba218"
    > is the salt - we'll assume that both are known.


    If you have access to 'a secure channel' which can be used to
    communicate two non-random strings which can be turnt into an
    encyrption key and initialization vector, why don't you just use a
    random key and a random IV and the same 'secure channel' to enable
    sender and recipient to share them?
    Rainer Weikusat, Aug 15, 2013
    #12
  13. Ben Morrow <> writes:
    > Quoth Charles DeRykus <>:


    [...]

    > ...that said, I've just looked at the source of 'openssl enc', and there
    > *is* an apparently-undocumented -md option to choose the hash function
    > to use for string2key, so it might be possible for the OP to switch to
    > SHA-1. However, there still isn't an option to add iterations, which is
    > almost more important.


    In the sense that neither one nor the other matters, yes. The hash is
    here solely used a 'compression function' capable of turning an
    arbitrarily long string into a fixed-size encryption key, not because
    of any cryptographic properties it might have. And using a more
    'expensive' calculation to derive this key is totally pointless _for
    encryption_ because it won't increase the amount of entropy in the
    input and once an attacker knows the key, he can decrypt away to his
    hearts content without caring about how it was created.

    It is not pointless when the derived key is supposed to be used in an
    authentication system relying on 'the /etc/passwd fallacy' that no one
    will ever be able to figure out the input (password) and thus, be able
    to impersonate another using, based on knowing output and algorithm
    alone. Or at least 'sort of not pointless': Expensive computations of
    today tend to become 'inexpensive computations of tomorrow' quickly
    ....
    Rainer Weikusat, Aug 15, 2013
    #13
  14. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:
    >>
    >> > In the Kerberos world, which I'm more familiar with, this function
    >> > is called 'string2key' and is considered cryptographically
    >> > significant. Modern Kerberos enctypes, in particular the AES
    >> > enctypes, use a function from PKCS#5, which uses SHA-1 rather than
    >> > MD5 and performs many iterations to increase the cost of a
    >> > dictionary attack.

    >>
    >> Ehh ... there is no way to do 'a dictionary attack' against Kerberos
    >> because the keys derived from user passphrases are supposed to be kept
    >> secret. There also wouldn't be any point in performing such a
    >> dictionary attack because the key derived from such a passphrase is
    >> what is actually used for authentication: Someone who knows that
    >> doesn't need to know the passphrase.

    >
    > Pretty-much any system which relies solely on human-memorable keys is
    > vulnerable to dictionary attacks. The fact Kerberos is vulnerable is
    > well-known: the attack goes something like this.
    >
    > Before a user can use a Kerberised network service, s/he has to log in
    > to Kerberos. This means the user sends an AS-REQ to the KDC,
    > containing their principal name and the TGT they are requesting, and the
    > KDC sends back an AS-REP containing (among other things) the user's TGT
    > for this session, encrypted with the user's own key. Wait for a user to
    > log on, and arrange to intercept the AS-REP (Kerberos explicitly assumes
    > this is possible; it's designed for use on insecure networks).
    >
    > Now you have a data structure, several parts of which are known or can
    > be guessed (for instance, the TGT contains the TGT principal in
    > plaintext), encrypted with the user's key. Guess a password, derive a
    > key from it, and try the decryption. If you get a valid TGT, you've just
    > worked out the user's key.


    That's not a dictionary attack on the _key_, aka 'someone recovering a
    "a secret input" from some scrambled transformation of that' by
    running the 'scramble' operation on 'words from some dictionary' and
    compare the output created in this step with the other. That's just
    ordinary brute-force decryption of something which has been encrypted
    with 'knowledge about the plaintext' being used to determine when the
    attack was successful.

    > Repeat until successful. The only limit on how long it takes is the
    > length of time required to derive the key, which is why slow hashes
    > with many iterations are important.


    Let's assume someone use a single letter password picked from the set
    of lowercase and uppercase letters. That would make 52 different
    possible passwords and the time required to determine that by brute
    force won't sigificantly depend on the speed of the key derivation
    algortim for any key derivation algorithm which is still 'fast enough'
    that a user cannot possibly throw the computer out of the window and
    buy a competing product in the time he has to wait while logging in.

    No matter how 'slow' the derivation function is, the main 'time
    consuming operation' needs to be 'going through the set of all
    possible inputs'.
    Rainer Weikusat, Aug 15, 2013
    #14
  15. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:
    >>
    >> > ...that said, I've just looked at the source of 'openssl enc', and there
    >> > *is* an apparently-undocumented -md option to choose the hash function
    >> > to use for string2key, so it might be possible for the OP to switch to
    >> > SHA-1. However, there still isn't an option to add iterations, which is
    >> > almost more important.

    >>
    >> In the sense that neither one nor the other matters, yes. The hash is
    >> here solely used a 'compression function' capable of turning an
    >> arbitrarily long string into a fixed-size encryption key, not because
    >> of any cryptographic properties it might have.

    >
    > Wrong. A hash which produces partially-predicatable output given
    > partially-predicatable input will map the thoroughly-non-uniform space
    > of passphrases onto a non-uniform subset of the space of possible keys,
    > effectively reducing the size of the key.


    In other words, "f(x) = 1 is not a suitable compression function for
    deriving an encryption key from some 'password' string". I agree with
    that.
    Rainer Weikusat, Aug 15, 2013
    #15
  16. Rainer Weikusat <> writes:
    > Ben Morrow <> writes:
    >> Quoth Rainer Weikusat <>:
    >>> Ben Morrow <> writes:
    >>> > In the Kerberos world, which I'm more familiar with, this function
    >>> > is called 'string2key' and is considered cryptographically
    >>> > significant. Modern Kerberos enctypes, in particular the AES
    >>> > enctypes, use a function from PKCS#5, which uses SHA-1 rather than
    >>> > MD5 and performs many iterations to increase the cost of a
    >>> > dictionary attack.
    >>>
    >>> Ehh ... there is no way to do 'a dictionary attack' against Kerberos
    >>> because the keys derived from user passphrases are supposed to be kept
    >>> secret.


    [...]

    >> Before a user can use a Kerberised network service, s/he has to log in
    >> to Kerberos. This means the user sends an AS-REQ to the KDC,
    >> containing their principal name and the TGT they are requesting, and the
    >> KDC sends back an AS-REP containing (among other things) the user's TGT
    >> for this session, encrypted with the user's own key. Wait for a user to
    >> log on, and arrange to intercept the AS-REP (Kerberos explicitly assumes
    >> this is possible; it's designed for use on insecure networks).
    >>
    >> Now you have a data structure, several parts of which are known or can
    >> be guessed (for instance, the TGT contains the TGT principal in
    >> plaintext), encrypted with the user's key. Guess a password, derive a
    >> key from it, and try the decryption. If you get a valid TGT, you've just
    >> worked out the user's key.

    >
    > That's not a dictionary attack on the _key_,


    After some superficial amount of research, it seems that Ben's more
    general use of the term is consistent with 'established practice' (eg,
    RFC494) while my more limited interpretation is not.
    Rainer Weikusat, Aug 15, 2013
    #16
  17. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:
    >> > Quoth Rainer Weikusat <>:
    >> >> Ben Morrow <> writes:
    >> >>
    >> >> > ...that said, I've just looked at the source of 'openssl enc', and there
    >> >> > *is* an apparently-undocumented -md option to choose the hash function
    >> >> > to use for string2key, so it might be possible for the OP to switch to
    >> >> > SHA-1. However, there still isn't an option to add iterations, which is
    >> >> > almost more important.
    >> >>
    >> >> In the sense that neither one nor the other matters, yes. The hash is
    >> >> here solely used a 'compression function' capable of turning an
    >> >> arbitrarily long string into a fixed-size encryption key, not because
    >> >> of any cryptographic properties it might have.
    >> >
    >> > Wrong. A hash which produces partially-predicatable output given
    >> > partially-predicatable input will map the thoroughly-non-uniform space
    >> > of passphrases onto a non-uniform subset of the space of possible keys,
    >> > effectively reducing the size of the key.

    >>
    >> In other words, "f(x) = 1 is not a suitable compression function for
    >> deriving an encryption key from some 'password' string". I agree with
    >> that.

    >
    > No, in other words, the compression function must be a cryptographically
    > strong hash, in the sense that it's impossible to predict any properties
    > of the output given knowledge of any properties of the input.


    As written, this requirement makes no sense: Except if a function
    performs a random mapping, predicting the output based on the input is
    always possible.

    > I believe MD5 is no longer considered to be cryptographically
    > strong.


    There's a known algorithm for creating different inputs yielding the
    same MD5 hash. This means MD5 is known to be a bad choice for digital
    signatures supposed to apply to 'document formats' which allow a
    prospective attacker to embed arbitrary 'binary noise' in ways which
    will usually not be noticed by a human 'consumer' of the document.
    Rainer Weikusat, Aug 15, 2013
    #17
  18. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:


    [...]

    >> Let's assume someone use a single letter password picked from the set
    >> of lowercase and uppercase letters. That would make 52 different
    >> possible passwords and the time required to determine that by brute
    >> force won't sigificantly depend on the speed of the key derivation
    >> algortim for any key derivation algorithm which is still 'fast enough'
    >> that a user cannot possibly throw the computer out of the window and
    >> buy a competing product in the time he has to wait while logging in.

    >
    > The difference between a computation which, done once, takes a
    > nanosecond and one which takes a whole second is a billionfold, yet a
    > user is extremely unlikely to notice an additional delay of a
    > second.


    And the difference between a brute-force attack which needs 52
    seconds to recover a password and one which needs 52 nanoseconds is
    practically irrelevant except if a 'large' number of passwords are
    supposed to be uncovered. And the algorithm may well need only 1s to
    recover the password when 52 $somethings can calculate different
    possibly correct results in parallell. Of course, two months from now,
    hardware or even software(!) capable of performing the '1s'
    calculation in a nanosecond will become available ...


    >> No matter how 'slow' the derivation function is, the main 'time
    >> consuming operation' needs to be 'going through the set of all
    >> possible inputs'.

    >
    > That simply isn't possible with human-memorable keys, especially if
    > users are allowed to choose their own passwords. (And not allowing them
    > to do so brings a whole other set of security problems, starting with
    > PostIt notes on monitors.)


    "It is not possible. It is possible but humans won't do that. If they
    do it, they will trigger "the PostIt" and then, we're all doomed, mark
    my words!" ?
    Rainer Weikusat, Aug 15, 2013
    #18
  19. Rainer Weikusat schrieb:

    > If you have access to 'a secure channel' which can be used to
    > communicate two non-random strings which can be turnt into an
    > encyrption key and initialization vector, why don't you just use a
    > random key and a random IV and the same 'secure channel' to enable
    > sender and recipient to share them?


    The secure channel is the users memory - quite good for passphrases, but
    very very bad for random numbers. And the salt is stored with the
    encrypted message.

    And for security reasons, I'm developing a perl script for reencryption
    (that is decrypting and then encrypting with a new passphrase. That way
    I might change the key generation algoririthm witghout pain, but for now
    the ciphertexts are encrypted in the same way "openssl enc" would do.

    Greetings

    Markus
    Markus Steinborn, Aug 15, 2013
    #19
  20. Charles DeRykus schrieb:

    > openssl will handle SHA so perhaps a very small patch to Crypt::CBC and
    > the script itself to replace Digest::MD5::md5 with Digest::SHA::sha1
    > might be another option...


    Well, I am not using openssl for encryption/decryption. But I found out
    by testing that key generation is compatible to openssl with default
    values, so asking the question this way seemed the best way to me.

    Currently we are using JavaScript for encryption/decryption - and I am
    building a perl script that allows changing passphrases by decrypting
    and then encrypting the data.

    In the middle term whis would allow canging the key generation
    algorithm, too. But for now, it is even more important allowing changing
    of passphrases.

    I'll consider changing the algorithm to use PBKDF2 (with SHA-3 as HMAC?).


    Markus
    Markus Steinborn, Aug 15, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    2,150
  2. M P
    Replies:
    1
    Views:
    463
  3. Jamis Buck

    OpenSSL and Key Passphrases

    Jamis Buck, Jul 28, 2004, in forum: Ruby
    Replies:
    2
    Views:
    158
    Eric Hodel
    Jul 29, 2004
  4. Redd Vinylene
    Replies:
    6
    Views:
    303
    Jakub Pawlowicz
    Nov 18, 2008
  5. pantagruel
    Replies:
    0
    Views:
    236
    pantagruel
    Feb 17, 2006
Loading...

Share This Page