RC4 şifreleme - PHP vs CommonCrypto (Objective-C)

2 Cevap php

Ben RC4 algoritması ile şifrelenmiş bir sunucu üzerinde bir XML dosyası var (http://rc4crypt.devhome.org)

function encrypt ($pwd, $data, $ispwdHex = 0)
    {
        if ($ispwdHex)
            $pwd = @pack('H*', $pwd); // valid input, please!

        $key[] = '';
        $box[] = '';
        $cipher = '';

        $pwd_length = strlen($pwd);
        $data_length = strlen($data);

        for ($i = 0; $i < 256; $i++)
        {
            $key[$i] = ord($pwd[$i % $pwd_length]);
            $box[$i] = $i;
        }
        for ($j = $i = 0; $i < 256; $i++)
        {
            $j = ($j + $box[$i] + $key[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        for ($a = $j = $i = 0; $i < $data_length; $i++)
        {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $k = $box[(($box[$a] + $box[$j]) % 256)];
            $cipher .= chr(ord($data[$i]) ^ $k);
        }
        return $cipher;
    }

İşte ben şifresini çözmek için kullanabileceğiniz nesnel-C kodu:

      NSData *dataToDecrypt = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.url.com/fileCrypted.xml"]] returningResponse:nil error:nil];
        const void *vplainText;
        size_t plainTextBufferSize;


            plainTextBufferSize = [dataToDecrypt length];
            vplainText = [dataToDecrypt bytes];


        CCCryptorStatus ccStatus;
        uint8_t *bufferPtr = NULL;
        size_t bufferPtrSize = 0;
        size_t movedBytes = 0;

        bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
        bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
        memset((void *)bufferPtr, 0x0, bufferPtrSize);

        NSString *key = @"mykey";
        //NSString *initVec = @"init Vec";
        const void *vkey = (const void *) [key UTF8String];
        const void *vinitVec = (const void *) [initVec UTF8String];

size_t keyLength = [[key dataUsingEncoding:NSUTF8StringEncoding] length]; 
        ccStatus = CCCrypt(kCCDecrypt,
                           kCCAlgorithmRC4,
                           0,
                           vkey,
                           kCCKeySizeDES,
                           nil,
                           vplainText,
                           plainTextBufferSize,
                           (void *)bufferPtr,
                           bufferPtrSize,
                           &movedBytes);
        if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
        /*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
        else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
        else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
        else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
        else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
        else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";

        NSString *result = [[ NSString alloc ] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIEncoding];

Kayıtlar çıkışı: BAŞARI ama benim sonuç (ben çok kodlamayı test edilmiş ancak ASCII iyi, cf PHP işlevi Ord gibi görünüyor ...). Iyi değil

Benim RC4 uygulama standart hem?

Edit: removed IV in Objective-C code Edit2: Objective-C KeyLength = password data length, removed option

2 Cevap

Eğer kriptografi ne yaptığınızı bilmiyorsanız, o zaman "haddeleme-your-kendi" felaket için bir emin yangın receipe olduğunu. Bana inanmak zorunda değilsiniz, The Cult of Schneier şifreleme "kendi roll" için denemek genel programcılar hakkında John VIEGA okudum. Yorumlanmıştır: Don't do it.

Bu bir dosya, ve ben makul bir küçük dosya tahmin ediyorum çünkü, gerekli şifreleme / şifre çözme yapmak için böyle SSL (OpenSSL ve diğerleri) veya OpenPGP (GPG, vb) gibi standartlar kullanılarak daha standart ve daha yüksek seviyeli kütüphaneleri kullanabilirsiniz . Objective-C (veya iPhone çevre) ve PHP hem de kütüphane veya SSL için modül desteği olduğuna inanıyorum.

RC4 hakkında Özellikle, yazmak için aldatıcı basit bir akış şifresi olduğunu, ancak uygulama ayrıntıları pisliği kolay inanılmazlık. The Misuse of RC4 in Microsoft Word and Excel görün ve Can you recommend RC4 128-bit encrypted software?, bir iyi bilinen tarihi, örneğin, ve güvenlik / kriptografi uzmanı (eski CTO ve PGP Corp kurucularından) bir öneri.


Added:

Php komut KeySize şifre verilerin ham uzunluğuna dayanmaktadır. Ayrıca herhangi bir PKCS7 Dolgu kullanmak değildir, bu yüzden bu alan (0) (CCryptor dere şifrelerin dolgu desteklemiyor ve php sürüm kesinlikle kullanmaz) sıfır olması gerektiğine inanıyoruz. Ben bunu şifre (bayt) uzunluğu (ikili veriler) olmak istiyorum inanıyorum oysa kod CCCrypt yılında, 8 byte (64 bit *) bir Keysize kullanılır.

Işlevler geçersiz kodaçımları geçerli belirlemek mümkün olmayacak kadar hayır MAC veya veri karma vardır.

Ben bu RC4 bu güvensiz uygulanmasında (PHP RC4crypt) ile uyumluluk için size yakın olsun düşünüyorum.

@ Mctylr bina, mümkünse kendi haddeleme kaçının. RC4 ihtiyacınız varsa, bir pre-built/tested kitaplığı kullanın: OpenSSL RC4. Yaklaşık 3 hatları ile tüm kodunuzu değiştirebilirsiniz.