Search code examples
objective-ccryptographyrijndael

Confusion regarding Rijndael/SHA256 encryption


I need to work out a decryption/encryption algorithm, but I'm confused regarding SHA256 / CBC / Salt / IV etc.

An example of a correctly encrypted string is:

U2FsdGVkX19IfIZtJ/48wk8z3ZRGDK8RD8agyQRhMrsOMsoIlVEcrzraOLo5IRBXjDkN1JUFnNrkvi2NA22IOTv00U97065tUNBQKEVXcaL0UJirtcqHlq8lN4pEm14ZokKXv8mUP8GkUKrOf37GhOugi/F/CQiILb57kIPrYPk=

It is Base64 encoded then Rijndael encoded. The first 8 characters are 'Salted__' and the next 8 characters I assume is some sort of salt (randomly generated).

The key I provided to encrypt this data is '12345678'.

The decrypted data should be:

2358442189442905:ZGF2aWQ=:1324515293:1.9.12:1:MC4wLjAuMCxub25lLzA=:LfcTMMYyUcwgL8keu3sMoNC/PFEKZy8fWFvo3rJvSdo

Apparently it is following Crypt::CBC::VERSION 2.29

I can't seem to decrypt the correctly encrypted string above. I have tried the following:

NSString *key = @"12345678";

NSData *test = [NSData dataFromBase64String:@"U2FsdGVkX19IfIZtJ/48wk8z3ZRGDK8RD8agyQRhMrsOMsoIlVEcrzraOLo5IRBXjDkN1JUFnNrkvi2NA22IOTv00U97065tUNBQKEVXcaL0UJirtcqHlq8lN4pEm14ZokKXv8mUP8GkUKrOf37GhOugi/F/CQiILb57kIPrYPk="];

unsigned char salt[8]; //get the salt out
[test getBytes:salt range:NSMakeRange(8, 8)];
NSData *saltData = [NSData dataWithBytes:salt length:8];

unsigned char data[128-16]; // remove the Salted__ and the 8 character salt
[test getBytes:data range:NSMakeRange(8, 128-8)];
test = [NSData dataWithBytes:data length:128-8];

NSMutableData *aeskey = [NSMutableData dataWithData:[key dataUsingEncoding:NSUTF8StringEncoding]];
[aeskey appendData:saltData]; // add the salt to the end of the key?

NSData *test2 = [test decryptedAES256DataUsingKey:key error:nil]; //Using a NSData+CommonCrypto library

Any ideas on how to decrypt this properly?

EDIT: more information: this is code related to what I am trying to implement.

elsif ($header_mode eq 'salt') {
$self->{salt} = $self->_get_random_bytes(8) if $self->{make_random_salt};
defined (my $salt = $self->{salt}) or croak "No header_mode of 'salt' specified, but no salt value provided"; # shouldn't happen
length($salt) == 8 or croak "Salt must be exactly 8 bytes long";
my ($key,$iv) = $self->_salted_key_and_iv($self->{passphrase},$salt);
$self->{key}  = $key;
$self->{civ}  = $self->{iv} = $iv;
$result  = "Salted__${salt}";
}

  my $self = shift;
  my ($pass,$salt)  = @_;

  croak "Salt must be 8 bytes long" unless length $salt == 8;

  my $key_len = $self->{keysize};
  my $iv_len  = $self->{blocksize};

  my $desired_len = $key_len+$iv_len;

  my $data  = '';
  my $d = '';

  while (length $data < $desired_len) {
    $d = md5($d . $pass . $salt);
    $data .= $d;
  }
  return (substr($data,0,$key_len),substr($data,$key_len,$iv_len));

Here is an implementation that I don't fully understand: http://pastebin.com/R0b1Z7GH http://pastebin.com/aYWFXesP


Solution

  • unsigned char salt[8]; //get the salt out
    [test getBytes:salt range:NSMakeRange(8, 8)];
    NSData *saltData = [NSData dataWithBytes:salt length:8];
    
    unsigned char data[128-16]; // remove the Salted__ and the 8 character salt
    [test getBytes:data range:NSMakeRange(8, 128-8)];
    test = [NSData dataWithBytes:data length:128-8];
    

    I think in your second block of code you are copying the wrong data. Try this:

    unsigned char data[128-16]; // remove the Salted__ and the 8 character salt
    [test getBytes:data range:NSMakeRange(16, 128-16)];
    test = [NSData dataWithBytes:data length:128-16];
    

    Your comment indicates that you want to skip both the Salted__ and the salt itself.

    Note that I haven't got a clue where the salt should go -- that's up to the protocol that you're trying to integrate with -- so I hope you've got that well-documented from another source.