سؤال

لقد قرأت المواضيع التالية وقد ساعدتني قليلاً، لكني أبحث عن المزيد من المعلومات.

كيفية كتابة تشفير وفك تشفير AES/CBC/PKCS5Padding باستخدام معلمة ناقل التهيئة لجهاز BlackBerry

تشفير جافا 256 بت AES

في الأساس، ما أفعله هو كتابة برنامج يقوم بتشفير الطلب ليتم إرساله عبر TCP/IP، ثم يتم فك تشفيره بواسطة برنامج خادم.يجب أن يكون التشفير AES، وبعد إجراء بعض الأبحاث اكتشفت أنني بحاجة إلى استخدام CBC وPKCS5Padding.لذا أحتاج في الأساس إلى مفتاح سري وحقن وريدي أيضًا.

التطبيق الذي أقوم بتطويره مخصص للهاتف، لذا أريد استخدام حزم أمان Java لإبقاء الحجم منخفضًا.لقد انتهيت من التصميم، لكني غير متأكد من تنفيذ IV والمفتاح المشترك.

إليك بعض التعليمات البرمجية:

// My user name
byte[] loginId = "login".getBytes();

byte[] preSharedKey128 = "ACME-1234AC".getBytes();
byte[] preSharedKey192 = "ACME-1234ACME-1234A".getBytes();
// 256 bit key
byte[] preSharedKey256 = "ACME-1234ACME-1234ACME-1234".getBytes();
byte[] preSharedKey = preSharedKey256;

// Initialization Vector
// Required for CBC
byte[] iv ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
IvParameterSpec ips = new IvParameterSpec(iv);


byte[] encodedKey = new byte[loginId.length + preSharedKey.length];

System.arraycopy(loginId, 0, encodedKey, 0, loginId.length);
System.arraycopy(preSharedKey, 0, encodedKey, loginId.length, preSharedKey.length);

// The SecretKeySpec provides a mechanism for application-specific generation
// of cryptography keys for consumption by the Java Crypto classes.

// Create a key specification first, based on our key input.
SecretKey aesKey = new SecretKeySpec(encodedKey, "AES");

// Create a Cipher for encrypting the data using the key we created.
Cipher encryptCipher;

encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Initialize the Cipher with key and parameters
encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey, ips);

// Our cleartext
String clearString = "33,8244000,9999,411,5012022517,0.00,0,1,V330";
byte[] cleartext = clearString.getBytes();

// Encrypt the cleartext
byte[] ciphertext = encryptCipher.doFinal(cleartext);

// Now decrypt back again...
// Decryption cipher
Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Initialize PBE Cipher with key and parameters
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey, ips);

// Decrypt the cleartext
byte[] deciphertext = decryptCipher.doFinal(ciphertext);

باختصار، ما ينبغي عليه فعله هو تشفير بعض الرسائل التي يمكن فك تشفيرها بواسطة الخادم دون أن يحتاج الخادم إلى الحصول على مفتاح أو IV من الهاتف.هل هناك طريقة يمكنني من خلالها القيام بذلك حيث يمكنني تأمين الوريد والمفتاح على الهاتف، ولا يزال لدي المفتاح والرابع معروفين بواسطة الخادم أيضًا؟لا تتردد في إخباري بتوضيح الأمور أكثر إذا لم تكن كذلك.

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

المحلول

وهناك عدد قليل من المشاكل مع التعليمات البرمجية. أولا وقبل كل شيء، هل حقا ينبغي أن تستخدم مولدا رئيسيا لتوليد المفاتيح السرية. مجرد استخدام بعض النص مباشرة قد عمل لبعض الخوارزميات، ولكن البعض الآخر مفاتيح ضعيفة وهكذا دواليك التي تحتاج إلى فحصها.

وحتى لو كنت تريد أن تفعل التشفير القائم على كلمة السر، يجب تشغيل كلمة السر من خلال خوارزمية اشتقاق مفتاح لإنتاج مفتاح، كما هو مبين في <لأ href = "https://stackoverflow.com/questions/992019/ جافا 256bit AES-التشفير / 992413 # 992413 "> جوابي لوالسؤال الذي سبق ذكرها.

وبالإضافة إلى ذلك، يجب عدم استخدام أسلوب عدم ARG getBytes() من String. هذا هو نظام أساسي التابعة. وإذا كان كل من السلاسل التي كنت ترميز تحتوي على أحرف فقط من مجموعة الأحرف US-ASCII، وجعلها واضحة لتحديد هذا التشفير بشكل واضح. وإلا، إذا منصات الهاتف ومركز الخدمة تستخدم المحارف المختلفة، والمفتاح وIV لن تتحول هي نفسها.

لوضع CBC، فمن الأفضل لاستخدام IV جديد لكل رسالة ترسلها. عادة، يتم إنشاء مراكز التحقيق CBC عشوائيا. وسائط أخرى مثل CFB وOFB <م> تتطلب إيفس فريدة لكل رسالة. يتم إرسالها إيفس عادة مع طول-إيفس المشفر لا تحتاج إلى أن تكون سرية، ولكن العديد من الخوارزميات كسر إذا تم استخدام IV يمكن التنبؤ به.

لا يحتاج الخادم للحصول على سر أو IV مباشرة من الهاتف. أنت <م> يمكن تكوين الملقم مع المفتاح السري (أو كلمة المرور، التي يستمد المفتاح السري)، ولكن في كثير من التطبيقات، وهذا من شأنه أن يكون تصميم سيئة.

وعلى سبيل المثال، إذا كان التطبيق سوف يتم توزيعهم على الهواتف من عدة أشخاص، أنها ليست فكرة جيدة بالنسبة لهم لاستخدام نفس المفتاح السري. يمكن للمرء أن المتطفلين استرداد مفتاح وكسر نظام للجميع.

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


تحديث:

وديفي هيلمان في وضع "سريع الزوال ساكنة" (و "ثابت ثابت" واسطة للغاية، على الرغم من أن هذا أقل من المرغوب فيه) ممكن بدون رسالة الأولية من الخادم إلى الهاتف، طالما يتم تضمين المفتاح العمومي للملقم في التطبيق.

والمفتاح العام الملقم لا تشكل نفس الخطر كما تضمين مفتاح سري مشترك في الهاتف. نظرا لأنه هو المفتاح العمومي، فإن التهديد يكون مهاجم الحصول على يديه (أو القرصنة عن بعد في) الهاتف واستبدال المفتاح العمومي الحقيقي مع مفتاح وهمية تسمح له تمثيل الخادم.

ووضع ثابت ثابت يمكن استخدامها، ولكنها في الواقع أكثر تعقيدا وأقل قليلا آمن. أن كل هاتف يحتاج الخاصة الزوج لها مفتاح فريد، أو أن تقع مرة أخرى إلى المشكلة الرئيسية سرية. على الأقل لن تكون هناك حاجة لخادم لتتبع الهاتف الذي لديه أي مفتاح (على افتراض أن هناك بعض آلية المصادقة على مستوى التطبيق، مثل كلمة المرور).

وأنا لا أعرف كيف بسرعة والهواتف. على سطح المكتب، وتوليد زوج مفاتيح سريع الزوال يستغرق حوالي 1/3 من الثانية. توليد معلمات ديفي هيلمان بطيء جدا. كنت تريد بالتأكيد إعادة استخدام المعلمات من المفتاح الخادم.

نصائح أخرى

لقد قمت بمشاريع مماثلة في ميدليت من قبل، لدي النصائح التالية لك:

  1. لا توجد طريقة آمنة لتخزين السر المشترك على الهاتف.يمكنك استخدامه ولكن هذا يقع ضمن فئة تسمى الأمن من خلال الغموض.إنه مثل نوع من الأمان "مفتاح تحت السجادة".
  2. لا تستخدم AES 256 بت، وهو غير متوفر على نطاق واسع.قد تضطر إلى تثبيت JCE آخر.لا تزال 128 بت AES أو TripleDES تعتبر آمنة.بالنظر إلى رقم 1، لا داعي للقلق بشأن هذا.
  3. يعد التشفير باستخدام كلمة مرور (مختلفة لكل مستخدم) أكثر أمانًا.ولكن لا يجب عليك استخدام كلمة المرور كمفتاح كما هو موضح في المثال.الرجاء استخدام PBEKeySpec (التشفير المعتمد على كلمة المرور) لإنشاء المفاتيح.
  4. إذا كنت قلقًا بشأن هجمات MITM (الرجل في المنتصف)، فاستخدم SSL.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top