
Simple and sane cryptographic wrapper library.
تحتوي حزمة NuGet AdvSim.Cryptography على مجموعة من الدوال الغلافية (wrapper functions) للتشفير، وهي قابلة لإعادة الاستخدام ومهيأة بإعدادات افتراضية سليمة وسهلة الاستخدام. تتوفر تفاصيل إضافية تحت العناوين الفرعية المختلفة أدناه.
تدعم حزمة NuGet AdvSim.Cryptography مجموعة واسعة من إصدارات .Net. بشكل عام، تتمتع الدوال المضمّنة في المكتبة بتغطية جيدة عبر الأطر المستهدفة (target frameworks). وعندما تُقيّد الدوال بأطر محددة، تُضاف شارة (badge) لإبراز هذا الاعتماد.
رابط NuGet: https://www.nuget.org/packages/AdvSim.Cryptography
عند تقديم مواد المفاتيح كجزء من مُنشئ العمليات التشفيرية، يُستخدم Rfc2898DeriveBytes لإرجاع مصفوفات بايت شبه عشوائية لتغذية عمليات التشفير وفك التشفير. هذه المصفوفات عالية الجودة، كما تضمن أن استدعاء الدالة نفسها بنفس مواد المفاتيح ينتج البذرة شبه العشوائية نفسها.
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
AES test = new AES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
TripleDES test = new TripleDES("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
RC4 test = new RC4("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
RC2 test = new RC2("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
MultiXOR test = new MultiXOR("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
تأخذ هذه الدالة مصفوفة بايت وتقوم إما بتشفيرها أو فك تشفيرها باستخدام مواد المفاتيح المقدمة في المُنشئ. عند الانتهاء، تُرجع مصفوفة بايت.
XTEA test = new XTEA("Lovecraft");
Byte[] bEncrypted = test.Encrypt(bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
لاحظ أن ECDH في v2.0.0 مدعوم عبر جميع إصدارات .Net المتوفرة في حزمة NuGet. ومع ذلك، وبسبب بعض قرارات تصميم .Net المشكوك فيها حقاً، فإن تحقيق التوافق التشغيلي (interop) بين جميع الأهداف المدعومة ليس بالأمر اليسير.
نتيجة لذلك، توجد اختلافات في التنفيذ بين Framework < .Net 4.7 وكل ما عداه. يجب أن يقع كلا العميلين في نفس المجموعة لتنفيذ تبادل المفاتيح بنجاح. إذا احتجت مثلاً إلى أن يكون أحد العميلين على .Net 6 والآخر على .Net 4.5.1، فعليك استخدام RSA بدلاً من ذلك.
لمعرفة المزيد حول إصدارات .Net، يمكنك الاطلاع على المورد التالي.
Framework < .Net 4.7
تدعم هذه الأهداف nistP256 فقط، ويمكن استخدام المكتبة كما يلي.
// Initialize both clients
ECDH test1 = new ECDH();
ECDH test2 = new ECDH();
// Exchange public keys
Byte[] bPublic1 = test1.GetPublicKeyArray();
Byte[] bPublic2 = test2.GetPublicKeyArray();
// Derive
test1.DeriveSharedKey(bPublic2);
test2.DeriveSharedKey(bPublic1);
// Encrypt / Decrypt
Byte[] bEncrypted1 = test1.Encrypt(bTestData);
Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
.Net 4.7+ || Standard 2.1 || .Net 6
تأخذ هذه الأهداف منحنىً كوسيط للمُنشئ.
public enum ECCurveType
{
brainpoolP160r1,
brainpoolP160t1,
brainpoolP192r1,
brainpoolP192t1,
brainpoolP224r1,
brainpoolP224t1,
brainpoolP256r1,
brainpoolP256t1,
brainpoolP320r1,
brainpoolP320t1,
brainpoolP384r1,
brainpoolP384t1,
brainpoolP512r1,
brainpoolP512t1,
nistP256,
nistP384,
nistP521
}
الاستخدام موضح أدناه.
// Initialize both clients
ECDH test1 = new ECDH(ECDH.ECCurveType.nistP521);
ECDH test2 = new ECDH(ECDH.ECCurveType.nistP521);
// Exchange public keys
Byte[] bPublic1 = test1.GetPublicKeyArray();
Byte[] bPublic2 = test2.GetPublicKeyArray();
// Derive
test1.DeriveSharedKey(bPublic2);
test2.DeriveSharedKey(bPublic1);
// Encrypt / Decrypt
Byte[] bEncrypted1 = test1.Encrypt(bTestData);
Byte[] bDecrypted2 = test2.Decrypt(bEncrypted1);
لاحظ أن هذه الوظيفة تتطلب حتماً عميلين، إذ لا يلزم تبادل المفاتيح العامة لاشتقاق سر مشترك كما هو الحال في ECDH. وبالطبع، كما هو موضح أعلاه، يمكنك إرسال مفتاحك العام عبر الشبكة إلى عميل آخر، والذي يمكنه بعد ذلك تشفير بيانات لا يمكنك أنت سوى فك تشفيرها.
RSA test = new RSA();
Byte[] bPublicKey = test.GetPublicKeyArray();
Byte[] bEncrypted = test.Encrypt(bPublicKey, bTestData);
Byte[] bDecrypted = test.Decrypt(bEncrypted);
البيانات التي يتم تشفيرها وفك تشفيرها مقصورة على نطاق الجهاز. لا يمكن فك تشفير البيانات خارج المضيف.
// Without entropy
DPAPI test = new DPAPI();
Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
// With entropy
DPAPI test = new DPAPI("Lovecraft");
Byte[] bEncrypted = test.EncryptUserDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptUserDPAPI(bEncrypted);
البيانات التي يتم تشفيرها وفك تشفيرها مقصورة على المستخدم الحالي. لا يمكن فك تشفير البيانات في سياق مستخدم مختلف.
// Without entropy
DPAPI test = new DPAPI();
Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
// With entropy
DPAPI test = new DPAPI("Lovecraft");
Byte[] bEncrypted = test.EncryptMachineDPAPI(bTestData);
Byte[] bDecrypted = test.DecryptMachineDPAPI(bEncrypted);
يمكن استخدام كلمة مرور لمرة واحدة مبنية على الوقت (TOTP) كفحص إضافي عند تنفيذ إجراءات للتحقق من أنها حقيقية. تكون رموز TOTP الناتجة عن المكتبة صالحة لدقيقة UtcNow كاملة. يمكن أيضاً استخدام هذه الأسرار الرقمية لتغذية مفاتيح متغيرة ديناميكياً لخوارزميات التشفير المتناظر. إذا استخدم العملاء نفس البذرة على أجهزة مختلفة، فسيحصلون على نفس TOTP.
// Generate a TOTP using a string seed
TOTP test = new TOTP("Lovecraft");
Console.WriteLine("[+] TOPT Code : " + oOTP.Code);
Console.WriteLine("[+] TOPT Last Code: " + oOTP.LastCode);
Console.WriteLine("[+] TOPT Validity : " + oOTP.Seconds);
// Validate TOTP based on string seed
Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.Code);
// Validate TOTP with forgiveness, this allows the previous TOTP
// to also be counted as valid
Boolean bValid = test.ValidateTOTP("Lovecraft", oTOTP.LastCode, true);