Porting C# CryptoSys-assisted 3DES encryption to Objective-C CommonCrypto issues -


i working on iphone app port of subset of .net c# functionality. must log server using 3des encrypted password (yes, know not optimal standard, please bear me).

so far, however, no joy. cannot replicate encryption in c# code. code in both c# in objective-c shares these common variables:

  1. strpassword unencrypted password, "secret"
  2. abplain byte array hex values of strpassword {73, 65, 63, 72, 65, 74, 02, 02}
  3. rpmpassword string of random characters.
  4. rpmpasswordasdata objective-c representation of rpmpassword nsdata using utf8 encoding
  5. abpassword byte array values of rpmpassword
  6. i've added code derive nlen in objective-c code below

here's c# code first:

static int iterationcount = 2048; static int keybytes = 24; static int blockbytes = 8;  byte[] abinitv = cryptosysapi.rng.noncebytes(blockbytes); byte[] abkey = cryptosysapi.pbe.kdf2(keybytes, abpassword, abinitv, iterationcount);  cryptosysapi.tdea cipher = cryptosysapi.tdea.instance(); cipher.initencrypt(abkey, mode.cbc, abinitv);  byte[] abcipher = cipher.update(abplain);  aboutput = new byte[abcipher.length + blockbytes]; (int = 0; < blockbytes; i++) aboutput[i] = abinitv[i]; (int = 0; < nlen + npad; i++) aboutput[blockbytes + i] = abcipher[i];  return cryptosysapi.cnv.tohex(aboutput) 

as can see, encrypted value returns concatenation of hex values of abinitv , abcipher.

i have been cribbing rob napier try , transform working objective-c code, far, it's not happening. producing abinitv , abcipher values of right length, , i'm concatenating them aboutput, being rejected server when try log in.

here's objective-c code (the constants declared, promise):

int nlen = [strpassword length]; int npad = ((nlen / blockbytes) + 1) * blockbytes - nlen;  nsdata *abinitv = [self randomdataoflength:blockbytes]; // salthex encryption const unsigned char *abinitvasbytes = [abinitv bytes];  nsdata *abkey = [self tdeakeyforpassword:strpassword salt:abinitv];  size_t movedbytes = 0;     nsmutabledata *abcipher = [nsmutabledata datawithlength:blockbytes];  cccryptorstatus result = cccrypt(kccencrypt,                                  kccalgorithm3des,                                  ccnopadding & kccmodecbc,                                  [abkey bytes],                                  kcckeysize3des,                                  [abinitv bytes],                                  abpassword,                                  [rpmpasswordasdata length],                                  abcipher.mutablebytes,                                  keybytes,                                  &movedbytes);  if (result == kccsuccess) {    nslog(@"abcipher == %@ \n", [abcipher description] );  }  nsmutabledata *aboutput = [nsmutabledata datawithcapacity:[abcipher length] + blockbytes]; const unsigned char *abcipherasbytes = [abcipher bytes];  (int = 0; < blockbytes; i++) {     [aboutput replacebytesinrange:nsmakerange(i, sizeof(abinitvasbytes[i])) withbytes:&abinitvasbytes[i]]; } (int = 0; < nlen + npad; i++) {     [aboutput replacebytesinrange:nsmakerange(blockbytes + i, sizeof(abcipherasbytes[i])) withbytes:&abcipherasbytes[i]];         }  return [encryptionutil nsdatatohex:aboutput]; 

and here supporting methods called in code above:

+(nsstring*) nsdatatohex:(nsdata*)data {     const unsigned char *dbytes = [data bytes];     nsmutablestring *hexstr =     [nsmutablestring stringwithcapacity:[data length]*2];     int i;     (i = 0; < [data length]; i++) {         [hexstr appendformat:@"%02x ", dbytes[i]];     }     return [nsstring stringwithstring: hexstr]; }  +(nsdata*)hextonsdata:(nsstring*)hex {     nsmutabledata* data = [nsmutabledata data];     int idx;     (idx = 0; idx+2 <= [hex length]; idx+=2) {         nsrange range = nsmakerange(idx, 2);         nsstring* hexstr = [hex substringwithrange:range];         nsscanner* scanner = [nsscanner scannerwithstring:hexstr];         unsigned int intvalue;         [scanner scanhexint:&intvalue];         [data appendbytes:&intvalue length:1];     }     return data; }  +(nsdata *)randomdataoflength:(size_t)length {     nsmutabledata *data = [nsmutabledata datawithlength:length];      int result = secrandomcopybytes(ksecrandomdefault,                                 length,                                 data.mutablebytes);      nsassert(result == 0, @"unable generate random bytes: %d",          errno);      return data; }  +(nsdata *)tdeakeyforpassword:(nsstring *)password                      salt:(nsdata *)salt {     nsmutabledata *     derivedkey = [nsmutabledata datawithlength:kcckeysize3des];      int result = cckeyderivationpbkdf(kccpbkdf2,            // algorithm                                   password.utf8string,  // password                                   password.length,  // passwordlength                                   salt.bytes,           // salt                                   salt.length,          // saltlen                                   kccprfhmacalgsha1,    // prf                                   iterationcount,         // rounds                                   derivedkey.mutablebytes, // derivedkey                                   derivedkey.length); // derivedkeylen      return derivedkey; } 

so, if can tell me i'm doing wrong, i'd sincerely appreciate it. if had hazard guess, i'd assume problem in 1 of 2 places:

  1. generating key, either in call to, or code of tdeakeyforpassword
  2. calling cccrypt.

that said, i've tried every available prf constant, padding , no padding.

i'm inexperienced encryption, i'd appreciate can offer.

thanks!

first, code samples seem different. c# code encrypting abplain. objc code encrypting abpassword. indicate abplain static, while abpassword random. have kind of padding going on in objc don't see in c# (maybe 0 padding? that's not standard way pad.)

if remove randomness, each implementation should return same result same input. first, hard-code random value (i use 0, random other number), , choose common abpassword. then, @ each step of process, make sure both implementations generate same result. significantly, abkey same, , abcipher, , aboutput. @ 1 of these points implementations diverge. (from quick reading, seem doing different things along.)

one thing confusing how switch between abpassword , rpmpassword. in 1 case pass abpassword, length of rpmpasswordasdata. feels place it's easy make mistake.

the length of abpassword unclear. assume it's multiple of 8, or else ccnopadding going blow up.

nsmutabledata has appenddata method. that's easier replacebytesinrange:…


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -