in reply to RSA encryption for (Ducth) iDeal payment

I'm not familiar with your exact problem, but I have worked a lot with perl and encryption. Since I don't have "Crypt::OpenSSL::RSA" installed, I used the openssl command. My documentation for openssl shows input from a file. ( Just a note, since non printable characters are very important in encryption/decryption I use a "|" before/after any printed results so I can see if any characters {carriage return, etc} are added. Any remember almost all encryption/decryption results are stated in bits, so be careful about wanting character results. )

As you can see we differ already in step 1 ( getting the SHA1 ). Your result may not be in printable hex format, and therefore you may be correct, but again I'm not familiar with the exact problem. If you have the openssl command on your system, try doing this manually to get the right answer and then implement the process using perl. Encryption is never easy!

#!/usr/local/bin/perl -w # # RSA_encryption_Ducth_iDeal_payment # use strict; use MIME::Base64 (); use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); #use Crypt::OpenSSL::RSA; my $string = "0021232117891234AcquirerStatusRes2004-11-02T15:05:03.750 +ZSuccess"; print ("\n\|$string:$string| (",length($string),")\n\n"); open (CTX, ">", "./ctx") or die "Could not open: $! \n"; print CTX "$string"; close CTX; my $sha1 = qx|openssl dgst -sha1 ./ctx|; print ("\n\$sha1:|$sha1| (",length($string),")\n\n"); #SHA encryption my $ctx = Digest::SHA1->new; $ctx->add($string); my $digest = $ctx->digest; my $len = length($digest); print ("SHA-1 DIGEST:$digest.. ($len)\n\n"); #RSA-encryption over the digest #Base64 encoding: my $encoded = MIME::Base64::encode($digest); my $len1 = length($encoded); print ("ENCODE:$encoded ($len1)\n\n"); __END__ #The result has to be (172 chars): #db82/jpJRvKQKoiDvu33X0yoDAQpayJOaW2Y8zbR1qk1i3epvTXi+6g+QVBY93YzGv4w+ +Va+vL3uNmzyRjYsm2309d1CWFVsn5Mk24NLSvhYfwVHEpznyMqizALEVUNSoiSHRkZUDf +XowBAyLT/tQVGbuUuBj+TkblY826nRa7U=

"Well done is better than well said." - Benjamin Franklin

Replies are listed 'Best First'.
Re^2: RSA encryption for (Ducth) iDeal payment
by Eric66 (Initiate) on May 06, 2011 at 07:30 UTC
    Hi,

    The first encryption has to be SHA-1.
    Using the prompt command 'openssl dgst -sha1'
    gives a different result compared to the Digest::SHA1

    'openssl dgst -sha-1' code results in:
    $string:0021232117891234AcquirerStatusRes2004-11-02T15:05:03.750ZSuccess| (64 chars)
    |$sha1:|SHA1(./ctx)= 0d1d60ffb10663e6d50cda8280015efb7b06154 | (54 chars)
    'Digest::SHA1 results:
    |$string:0021232117891234AcquirerStatusRes2004-11-02T15:05:03.750ZSuccess| (64 chars)
    |Digest::SHA1: @ÑÖûf>mPͨ(ï·°aT| (20 chars)

    The result had to be a 160 bits output. (160 bites is 20 chars)

    In the iDeal manual (sorry but it's in Dutch) http://www.rabobank.nl/images/handleiding_ideal_professional_2966322.pdf (page 26) there is a part where a signature is made using the command:
    echo "test" | openssl dgst -sha1 -verify cert.pem -signature test.sig
    where cert.pem is my certificate and test.sig is the output.
    It give an error: 'unable to load key file', although the file exists and is accessible

    Should I use the openssl command or perform the 3 encryption steps by my self?

      First a couple of comments.

      • If you use <code> . . . </code> it will help all of us understand your code vs. data better.

      • I hinted at the response about 2 different answers to help you understand how difficult de/encryption is. What I wanted to demonstrate was the carriage return that was returned by openssl. If you unpack your answer

                  unpack ("H40", $digest);

        you'll see we did get the same result. My answer was printable hex, and your answer was the raw hex characters. Good for computers, bad for people viewing the results. But that result may have to be chopped or converted before it can be used as input into the next step.

      • This is a nit, but using the word 'byte' ( 8 bits ) is preferred over 'chars' ( re. utf8 ).
                  20 bytes is exactly 160 bits.
                  20 chars may be 160 bits, 320 bits, 480 bits, etc.

      I googled your question, and found many people asking the same question as you, so you're not alone with the confusion about step 2. I did see a reference to 32/64 bit hardware and another about network order bytes(big-endian). I believe openssl removes those dependences.

      "Well done is better than well said." - Benjamin Franklin

        Nothing like replying to your own post, but I am looking at the description of the process in the Dutch manual. It looks like you need a copy of their test "cert.pem" and test "test.sig" files to get the exact results they show. the openssl command allows you to specify -in for input file and -out for output file. Much better than the example below. I think they have the message in a file (./test), and should be cating the file for input to openssl. I think -in and -out would be easier to manage ( but that's your call! )

        echo "test" | openssl dgst -sha1 -verify cert.pem -signature test.sig

        The process (from the Dutch manual) seems to be:

        • Generate message ( your $string )
        • get SHA1 of message
        • encrypt SHA1 160 bit (20 karakters) with your private DES 1024 bit key (cert.pem) and sign with signature (test.sig).

        Nice that they show you the result, but without the exact files "cert.pem" and "test.sig", you will not get their result.

        You may be working but can't prove it with-out the above files. Also they will need your public key in order to verify the signature and decrypt the message.

        Looks to me, you will need help from their IT dept to verify that it works.

        Sorry about the "byte" comment, I assume you were just translating "karakters" to "chars".

        "Well done is better than well said." - Benjamin Franklin