Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 13 of 13
  1. #1
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts

    Question php + c# + DES3 + PKCS Padding = nightmare guru's needed

    ok so I'm having a rather odd issue with some php to c# based encrypting as in it sometimes works 100% and sometimes works randomly ie: works for some variables not for others
    Now today i'm having one of the part working days (tomorrow it'll probably work perfectly )

    Basically I'm encrypting a load of variables with a pre-set key and sending them to a remote server thats running a c# platform. I think the problem lies in a combination of day + blocksize creation for padding but I can't pin it down and was just wondering if a fresh set of eyes may resolve it for me.

    Here's the encrypt + padding code including our key generation system as the key is a combination of a static key string + day effectors

    PHP Code:
    function pkcs7_pad($text$blocksize) {
                   
    // padding function required to make php match C#
                
    $pad $blocksize - (strlen($text) % $blocksize);
                return 
    $text str_repeat(chr($pad), $pad);
    }

    function 
    desencrypt($input) {
                
    // SSOKey as supplied
                
    $ssokey =  'g4h5cjdf57hjjdpjo41xd6awe7qwxvxz';
                
    //calc date offset
                
    $todaysdate date("z")+1;
                
    //update key with todays date
                
    if (strlen($todaysdate)>0) {
                    
    $newkey $todaysdate.substr($ssokey,strlen($todaysdate),strlen($ssokey));
                }
                
    //decode key to binary
                
    $key base64_decode($newkey);
                
    /* Open mcrypt module */
                
    $td mcrypt_module_open(MCRYPT_3DES''MCRYPT_MODE_ECB'');
                
    $iv mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
                
    $blockSize mcrypt_get_block_size(MCRYPT_3DESMCRYPT_MODE_ECB);
                
    //pad out input to match C# defaults
                
    $input pkcs7_pad($input$blockSize);
                
    //$input = pkcs7_pad($input, 8);
                /* Intialize encryption */
                
    mcrypt_generic_init($td$key$iv);
                
    /* Encrypt data */
                
    $encrypted mcrypt_generic($td$input);
                
    /* Terminate encryption handler */
                
    mcrypt_generic_deinit($td);        
                
    /* close module */
                
    mcrypt_module_close($td);
                
    /* return encrypted string */
                
    return base64_encode(trim($encrypted));


    now if I encrypt the value 6 using htmlentities(desencrypt("6"))
    I get kaKbuHmi1JU= in both PHP and C# which is perfect.
    However if I encrypt a value of 1 I get Cd7JeO2YckI= for C# and 3sl47ZhyQg== for PHP which is obviously wrong.

    All other strings being encoded today are working just fine its just the issue with the number 1 being encrypted and as said it sometimes works perfectly other times it doesn't like today.

    Can anyone see anything obviously wrong with my code or padding. Or have you got some suggestions of stuff I can test/attempt.

    Any help will be much appreciated with many thanks
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #2
    Super Moderator Inigoesdr's Avatar
    Join Date
    Mar 2007
    Location
    Florida, USA
    Posts
    3,642
    Thanks
    2
    Thanked 405 Times in 397 Posts
    Quote Originally Posted by hinch View Post
    However if I encrypt a value of 1 I get Cd7JeO2YckI= for C# and 3sl47ZhyQg== for PHP which is obviously wrong.
    The result from C# has a tab at the beginning, and your PHP version doesn't. That is probably being stripped by this:
    Code:
    return base64_encode(trim($encrypted));
    You should either remove the trim() or trim it in C#.

  • #3
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    ok i can trim it in the C# but that then raises the question why it works sometimes and other times doesn't.

    its strange because the trim() in the php was put in because php was adding in an extra space at the end of the pre-encrypted string which was initially causing wrong strings this resolved the first part of of the problem

    I'll add in a trim on the c# side of things and see if that helps
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #4
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    here's an interesting one today its encrypting the variable with value 1 fine today

    its now failing on a variable with value 2641 php creates I5hRDOJTWA== and c# creates ICOYUQziU1g=
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #5
    New to the CF scene
    Join Date
    May 2011
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hinch - could you comment on getting .NET encrypted strings decrypted in PHP?

    I am trying to decrypt a cookie string that was encrypted in .NET, using TripleDES. The Key is a 16Character ASCII string, that has allegedly been encoded into HEX. What confuses me is that this creates a 32Character string (256bits), but everything I've read says that TripleDES can only accept a 198bit (24characters) string.

    PHP's mcrypt_decrypt certainly only uses the first 24 characters in a supplied string.

  • #6
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    yeah there is a difference in key length between the 2 thats where the padding comes into play.

    For decryption you'll have to strip the padding after decryption (it should be padded with zero's) I've not actually written the decryption function for php because i need to go from encrypt in php to decrypt in c# other way around to you.

    If I get chance I'll look into knocking together a php decrypt function for you just abit busy this week
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #7
    New to the CF scene
    Join Date
    May 2011
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by hinch View Post
    yeah there is a difference in key length between the 2 thats where the padding comes into play.

    For decryption you'll have to strip the padding after decryption (it should be padded with zero's) I've not actually written the decryption function for php because i need to go from encrypt in php to decrypt in c# other way around to you.

    If I get chance I'll look into knocking together a php decrypt function for you just abit busy this week
    I appreciate that the string to be encrypted will be padded - but what about the key-length issue??

    Or does the Key I'm using have to be padded?? How would that work when the key is too long for php?? Or do I pad it before Hex-ing it?? I've tried that and it just creates an even longer Hex string which fires the same error/warning in php.

  • #8
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    i believe that if you have say a 32 char key and php only accepts 24 then it takes the first 24 chars of the key.

    though don't hold me to that.
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #9
    Super Moderator Inigoesdr's Avatar
    Join Date
    Mar 2007
    Location
    Florida, USA
    Posts
    3,642
    Thanks
    2
    Thanked 405 Times in 397 Posts
    Quote Originally Posted by hinch View Post
    here's an interesting one today its encrypting the variable with value 1 fine today

    its now failing on a variable with value 2641 php creates I5hRDOJTWA== and c# creates ICOYUQziU1g=
    The C# version has a space at the beginning which is causing the difference.

  • #10
    New to the CF scene
    Join Date
    May 2011
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by hinch View Post
    i believe that if you have say a 32 char key and php only accepts 24 then it takes the first 24 chars of the key.

    though don't hold me to that.
    Yes, that's what happens. (and php also throws a warning).

    But if the .NET encryption process DOES (for some reason) accept a 32 character key, then it would appear that PHP can't decrypt the string properly? I have trouble believing that this would be the case.

  • #11
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    Quote Originally Posted by Inigoesdr View Post
    The C# version has a space at the beginning which is causing the difference.
    yeah i figured the additional = at the end was meaning an additional space i've removed the trim() from my encrypt now which appears to have fixed it however I won't know for sure until dates trip over back to single digit days as I suspect on single digit days we overpad as opposed to underpad (as now) and so the trim will have to return.

    if thats the case I'll just have to put a detect in there for day length and take it from there
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #12
    Regular Coder hinch's Avatar
    Join Date
    Sep 2005
    Location
    UK
    Posts
    923
    Thanks
    25
    Thanked 80 Times in 80 Posts
    Quote Originally Posted by Riceburner View Post
    Yes, that's what happens. (and php also throws a warning).

    But if the .NET encryption process DOES (for some reason) accept a 32 character key, then it would appear that PHP can't decrypt the string properly? I have trouble believing that this would be the case.
    I believe this issue is well documented around the net and is indeed the case I'm not entirely sure how it'd be resolved though and I haven't really had chance to look into it unfortunately still attempting to solve my own issue at the moment
    A programmer is just a tool which converts caffeine into code

    My work: http://www.fcsoftware.co.uk && http://www.firstcontactcrm.com
    My hobby: http://www.angel-computers.co.uk
    My life: http://www.furious-angels.com

  • #13
    New to the CF scene
    Join Date
    May 2011
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by hinch View Post
    yeah i figured the additional = at the end was meaning an additional space i've removed the trim() from my encrypt now which appears to have fixed it however I won't know for sure until dates trip over back to single digit days as I suspect on single digit days we overpad as opposed to underpad (as now) and so the trim will have to return.

    if thats the case I'll just have to put a detect in there for day length and take it from there
    Could you use double digit days? (01,02 etc)??

    I'm waiting to see what the .NET devs have done in their encryption process to possibly solve my issue.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •