سؤال

أحتاج إلى تشفير سلسلة على iPhone وإرسالها إلى خدمة ويب .NET ل فكيب فك التشفير. أنا قادر على تشفير / فك تشفيرها على iPhone ومع .NET، ولكن لا يمكن فك تشفير السلاسل المشفرة من iPhone بواسطة .NET. الخطأ الذي أحصل عليه هو "الحشو غير صالح ولا يمكن إزالته".

كود .NET من:http:/blog.realcoderscoding.com/index.php/2008/07/dot-net-encryption-simple-aes-wrapper/

يستخدم رمز iPhone رمز العينة من: http://nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/

AFAIK إعداداتي الرئيسية هي نفسها:

result.BlockSize = 128; // iPhone: kCCBlockSizeAES128
result.KeySize = 128; // kCCBlockSizeAES128
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7; // kCCOptionPKCS7Padding

حاولت طرق مختلفة لتوليد النص المشفر. مرحبا / مرحبا هو:

E0PNMBTG / 3CT3W + 92CDW1Q == في .NET

yrke5z7p7mnqx9 + cbbvnqq == على iPhone

و "Openssl ENC -AES-128-CBC -NOSALT -A - في Hello.txt - Pass Pass: Hello" يولد: QA + UL + R6ZMR7YHIPMCHSBQ ==

تحديث: لقد قمت بنشر رمز العمل لهذا هنا.

هل كانت مفيدة؟

المحلول

على الأقل، أنت تستخدم ناقلات التهيئة المختلفة (IV).

  • يستخدم رمز .NET مفتاح IV.

    private static AesCryptoServiceProvider GetProvider(byte[] key)
    {
        //Set up the encryption objects
        AesCryptoServiceProvider result = new AesCryptoServiceProvider();
        byte[] RealKey = Encryptor.GetKey(key, result);
        result.Key = RealKey;
        result.IV = RealKey;
        return result;
    }

    و

    private static byte[] GetKey(byte[] suggestedKey, AesCryptoServiceProvider p)
    {
        byte[] kRaw = suggestedKey;
        List kList = new List();
        for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8 )
        {
            kList.Add(kRaw[i % kRaw.Length]);
        }
        byte[] k = kList.ToArray();
        return k;
    }

    والتي يجب أن تكون: kList.Add(kRaw[(i / 8) % kRaw.Length]);. وبعد خلاف ذلك مفتاح طول٪ 8 == 0 سوف تستخدم نفس الحرف مرارا وتكرارا، دوه!

    وبالتالي الرابع (والمفتاح) المستخدمة بواسطة .NET هو: hleolhleolhleolh. وبعد هذا ليس جزءا من واجهة برمجة التطبيقات، بل يرجع إلى رمز التفاف الذي أشرته في (الذي يحتوي على خطأ خطير فيه ...).

  • يستخدم رمز iPhone 0 ل IV.

    // Initialization vector; dummy in this case 0's.
    uint8_t iv[kChosenCipherBlockSize];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));
  • openssl افتراضيا بإعداد الملح الذي تم إنشاؤه عشوائيا (وهذا هو السبب في أن الإخراج أطول!).

إخراج Openssl أكثر أمانا لأنه يقوم بإعداد ناقلات التهيئة العشوائية. يبدو أن البايت القليلة الأولى من سلسلة فك التشفير Base64 "مملحة". يمكنك أيضا أن تسأل Openssl لعدم استخدام الملح (-NOSALT) و / أو توفير الرابع (-iab).

بشكل أساسي، يستخدم iPenssl، .NET، و iPhone نفس التشفير، تحتاج فقط إلى توخي الحذر من كيفية تهيئة واجهات برمجة التطبيقات مع مفتاح التشفير ومتاجر التهيئة.

نصائح أخرى

في ج #

void test(){
   string ctB64 = encrypt("hola");
   Console.WriteLine(ctB64);  // the same as in objective-c
}

string encrypt(string input)
        {
            try
            {
                // Create a new instance of the AesManaged class.  This generates a new key and initialization vector (IV).
                AesManaged myAes = new AesManaged();

                // Override the cipher mode, key and IV
                myAes.Mode = CipherMode.CBC;
                myAes.IV = new byte[16] { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in objective-c
                myAes.Key = Encoding.UTF8.GetBytes(“0123456789123456”);
                //CipherKey;  // Byte array representing the key
                myAes.Padding = PaddingMode.PKCS7;

                // Create a encryption object to perform the stream transform.
                ICryptoTransform encryptor = myAes.CreateEncryptor();

                // perform the encryption as required...
                MemoryStream ms = new MemoryStream();
                CryptoStream ct = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
                byte[] binput = Encoding.UTF8.GetBytes(input);
                ct.Write(binput, 0, binput.Length);
                ct.Close();
                byte [] result = ms.ToArray();
                return Convert.ToBase64String(result);
            }
            catch (Exception ex)
            {
                // TODO: Log the error 
                Console.WriteLine(ex);
                throw ex;
            }

        }

· في الهدف - ج، أضف مكتبة شرك الكوز https://github.com/kelp404/cocoaSecurity.

#import "CocoaSecurity.h"
#import "Base64.h"

…

- (void) test{
 unsigned char bytes[] = { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in c#

    NSData *iv = [NSData dataWithBytesNoCopy:bytes length:16 freeWhenDone:YES];
    NSData* key =   [@"0123456789123456" dataUsingEncoding:NSUTF8StringEncoding];

    CocoaSecurityResult *result = [CocoaSecurity aesEncrypt:@"hola" key:key iv:iv];
   NSLog(@"%@", result.base64); // the same as in c#


    NSData *data = [NSData dataWithBase64EncodedString:result.base64];
    CocoaSecurityResult *result2 = [CocoaSecurity aesDecryptWithData:data key:key iv:iv];

    NSLog(@"%@", result2.utf8String); // show "hola"

}

هل أنت متأكد من أنك تستخدم نفس المفتاح AES في الاختبارات الخاصة بك؟ يستخدم مثال Openssl في منشورك كلمة مرور يقوم بها OPENSSL بمفتاح ورابع من (وربما يستخدم الملح أيضا.

قم بإنشاء مفتاح عشوائي 128 بت وتحديد هذا المفتاح بتنسيق سداسي عشري إلى OpenSSL مع:

openssl enc -aes-128-cbc -a -in hello.txt -K KEY_IN_HEX -iv 0

يجب أن لا تستخدم IV = 0 في أي نظام آمن، ولكن لاختبار قابلية التشغيل البيني، فلا بأس.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top