PDA

View Full Version : جلوگیری از رمزگشایی با پسورد دیکشنری در الگوریتم های رمزنگاری



negar.rafie
پنج شنبه 19 شهریور 1394, 15:14 عصر
سلام
فرض کنید ما از الگوریتم aes استفاده کردیم و یه یک رشته را با یک کلید رمز کردیم
حالا اگر این رشته رمز شده برسه به دست یه هکر اون هکر میتونه با داشتن یه پسورد لیست کلید را پیدا کنه
حالا یا راهی هست که بشه از این کار جلوگیری کرد و هکر به هیچ عنوان نتونه به متن اصلی دست پیدا کنه؟

group45
پنج شنبه 19 شهریور 1394, 15:32 عصر
هر چیزی که بدست انسان ساخته بشه بدست انسانم میشه مهندسی معکوسش کرد و یا ارتقاش داد
شما فقط میتونید مساله رو پیچیده تر کنید

negar.rafie
پنج شنبه 19 شهریور 1394, 16:09 عصر
خب چگونه باید اینکار را کرد؟

Reza-HNA
پنج شنبه 19 شهریور 1394, 18:16 عصر
همونطور که جناب group45 گفتند ، این کار با مهندسی معکوس قابل انجامه .
برای این کار هم برنامه رو دیباگ میکنی و با تریس کردن به شروط مورد نظر میرسیم و چگونه رمز شدن اطلاعات رو میفهمیم و در نهایت معکوسش میکنیم . برای جلوگیری هم کار خاصی نمیشه انجام داد فقط میتونیم از خود برنامه محافظت کنیم یا دستورات رو مبهم کنیم تا رسیدن به شروطمون سخت بشه .
در کل کرکر خیلی سمج و با تجربه باشه آخر کرکش میکنه :لبخند:

negar.rafie
جمعه 20 شهریور 1394, 09:04 صبح
پس چطور میگن لگوریتم AES قابل شکستن نیست تا 100 سال دیگه؟

group45
جمعه 20 شهریور 1394, 12:01 عصر
با سلام
این زمان به دلیل فرمت کدگذاری اوناست. مثلا با روش 128 بیتی کدگذاری کنه یا بالاتر که هرچی بالاتر بره تعداد بررسی ها هم نمایی افزایش پیدامیکنه در نتیجه مدت زمان بیشتری برای بررسی کردن تک تک کلمه های تولید شده برای مقایسه و باز کردن فایل هست
امیدوارم که متوجه شده باشید...

FastCode
شنبه 21 شهریور 1394, 05:05 صبح
سلام.
راه داره.و با مهندسی معکوس هم قابل شکستن نیست.

static Rijndael CreateRijndael (byte[] userID, string password, string pepper, int rounds = 8)
{
if (userID == null) throw new ArgumentNullException ("userID");
if (password == null) throw new ArgumentNullException ("password");
if (pepper == null) throw new ArgumentNullException ("pepper");
if (rounds < 1) throw new ArgumentOutOfRangeException ("rounds");

string passpepper = password + pepper;
Rijndael Rij = Rijndael.Create ();
Rij.KeySize = 256;
Rij.Padding = PaddingMode.ISO10126;
Rij.Mode = CipherMode.CBC;
Rfc2898DeriveBytes aesKey = new Rfc2898DeriveBytes (passpepper, userID, 65536 * rounds);
Rij.Key = aesKey.GetBytes (Rij.KeySize / 8);
Rij.IV = aesKey.GetBytes (Rij.BlockSize / 8);
return Rij;
}

negar.rafie
شنبه 21 شهریور 1394, 08:50 صبح
اگر به ین صورت عمل کنیم یعنی با پسورد لیست نمیشه رمزگشایی کرد؟
1- میشه بگید چرا نمیشه با پسورد لیست رمزگشایی کرد؟
2- اگر هکر سورس برنامه را داشته باشه چی ؟
ممنون

FastCode
شنبه 21 شهریور 1394, 18:35 عصر
اگر به ین صورت عمل کنیم یعنی با پسورد لیست نمیشه رمزگشایی کرد؟
1- میشه بگید چرا نمیشه با پسورد لیست رمزگشایی کرد؟
2- اگر هکر سورس برنامه را داشته باشه چی ؟
ممنون

اگر سورس رو داشته باشه و دیکشنری هم داشته باشه با CPU شکتسن هر رمز 4 رقمی یک روز طول میکشه.(IS های AES-NI و SSE2/3 SSSE3 روی این سرعت خیلی تاثیر دارند)
اگر میخواهید با GPU غیرممکن بشه میتونید الگوریتموتون رو memory-hard بکنید که اونطوری شکستن هر رمز چند ماه طول میکشه.
اگر امنیت خیلی مهمه میتونید اون rounds رو بکنید مثلا 64 و مثلا 1048576+24+1(این تعداد محاسبه برای کارتهای گرافیک یک مقدار سخت تره.هم کدنویسی و هم حافظه مورد نیاز) بار sha256 ه hash محاسبه شده رو با خودش concat بکنید که میشه 32MB و یک بایت در میون برعکس با خودش xor کنید و از اون برای ورودی PBKDF2 استفاده کنید.(یعنی الگوریتم رو طوری بنویسید که همزمان به ابتدا و انتهای آرایه نیاز داشته باشد و حداقل sqrt(n) بار این نیاز وجود داشته باشد) ولی اون موقع login کلی طول میکشه.
یعنی اینطوری

10:a=hash(input)
20:a=a+hash(a)
30: goto 20 1048576+24+1 times
40: revert a
...

پ.ن.
در کل باید توجه داشته باشید رمز وقتی رمز هست که باهاش چیزی رو رمزنگاری کنید که برنامه نتونه بدون اون به فعالیتش ادامه بده.یعنی اطلاعات برنامه
روش محاسبه sha256 رو حتما مطالعه کنید.این الگوریتم میتواند برای هر تکه ورودی از قبل محاسباتی را انجام دهد که به قطعات دیگر وابسته نیست.(این به ضرر شماست)

negar.rafie
یک شنبه 22 شهریور 1394, 00:18 صبح
ممنون واقعا ممنون
خواهشا کمک کنید تا این بحث به نتیجه برسه جناب fastcode

من در کل برای رمزنگاری از کد زیر استفاده کردم و این کدها نوشتم:

private byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = passwordBytes;
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (CryptoStream cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}



public string EncryptText(string text, byte[] passwordBytes)
{
byte[] originalBytes = Encoding.UTF8.GetBytes(text);
byte[] encryptedBytes = null;
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
int saltSize = GetSaltSize(passwordBytes);
byte[] saltBytes = GetRandomBytes(saltSize);
byte[] bytesToBeEncrypted = new byte[saltBytes.Length + originalBytes.Length];
for (int i = 0; i < saltBytes.Length; i++)
{
bytesToBeEncrypted[i] = saltBytes[i];
}
for (int i = 0; i < originalBytes.Length; i++)
{
bytesToBeEncrypted[i + saltBytes.Length] = originalBytes[i];
}
encryptedBytes = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
return Convert.ToBase64String(encryptedBytes);
}



byte[] passwordBytes = Encoding.UTF8.GetBytes(txtKey.Text);
textEncrypt.Text = EncryptText(txtPlaintext.Text, passwordBytes);

برای من امنیت مهمه ولی نمیخوام سرعت برنامه خیلی بیاد پایین
حالا اقا بهروز (fastcode)با توجه به گفته های شما و اون تیکه کدی که شما نوشتید باید کدوم قسمت ها را تغییر بدیم؟
ممنون

FastCode
یک شنبه 22 شهریور 1394, 07:05 صبح
سالت باید برای باز کردن رمز استفاده بشه. یه جایی ذخیرش کنید.
مثلا توی تیبل کاربر
سالت نباید به ورودی اضافه بشه.
سالت باید به رمز اضافه بشه.

ببخشید الان فرصت ندارم بنویسم. بعدا کاملتر پاسخ میدم

FastCode
شنبه 28 شهریور 1394, 09:44 صبح
این بهتره. البته هنوز خیلی جای کار داره:


using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace AEStest
{
class MainClass
{
static void Main ()
{
string iv;
string text = EncryptText ("Hello world!", new byte[] { 0x89, 0x3A, 0x24, 0xA2, 0x3F, 0x4b, 0xfa, 0x18 }, new byte[]{ 0x23, 0x54, 0x40, 0x89, 0x23 }, out iv);
Console.WriteLine ("Text:{0}", text);
Console.WriteLine ("IV:{0}", iv);
}

static void Clear (byte[] bytes)
{
for (int n = 0; n != bytes.Length; n++) {
bytes [n] = 0xff;
}
for (int n = 0; n != bytes.Length; n++) {
bytes [n] = 0x00;
}
}

public static string EncryptText (string text, byte[] salt, byte[] passwordBytes, out string iv)
{
byte[] ivBytes;
byte[] aesBytes = AES_Encrypt (Encoding.UTF8.GetBytes (text), salt, passwordBytes, out ivBytes);
iv = Convert.ToBase64String (ivBytes);
string outText = Convert.ToBase64String (aesBytes);
Clear (aesBytes);
return outText;
}

/// <summary>
/// Encrypts and eats your variables.
/// </summary>
static byte[] AES_Encrypt (byte[] bytesToBeEncrypted, byte[] salt, byte[] passwordBytes, out byte[] iv)
{
MemoryStream ms = new MemoryStream ();
using (RijndaelManaged AES = new RijndaelManaged ()) {
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes (passwordBytes, salt, 1001);
AES.Key = key.GetBytes (AES.KeySize / 8);
AES.IV = iv = key.GetBytes (AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (CryptoStream cs = new CryptoStream (ms, AES.CreateEncryptor (), CryptoStreamMode.Write)) {
cs.Write (bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close ();
cs.Clear ();
}
AES.Clear ();
Clear (bytesToBeEncrypted);
Clear (salt);
Clear (passwordBytes);
return ms.ToArray ();
}
}
}
}

negar.rafie
شنبه 28 شهریور 1394, 15:01 عصر
ممنون
ولی میشه همون خودم ر تغییر بدید؟
میخوام بدونم کجا اشتباه داره و یاد بگیرم
بی زحمت کد خودم را هر جاش اشتباه است را بنویسید و همینطور رمزگشایی اون را

drsina
شنبه 28 شهریور 1394, 20:32 عصر
یه سوال برای چی تا 100 سال دیگه قابل بازیابی نیست ؟! خب یه نفر brute force کنه با چندتا کامپیوتر که فکر نکنم با یه رمز قوی چند روز بیشتر طول بکشه .
و یه چیز دیگه که به نظر مهمتره یه نفز از روو سورس برنامه پسورد رو برمی داره ! میشه اینا کاریش کرد ؟!

FastCode
شنبه 28 شهریور 1394, 22:37 عصر
یه سوال برای چی تا 100 سال دیگه قابل بازیابی نیست ؟! خب یه نفر brute force کنه با چندتا کامپیوتر که فکر نکنم با یه رمز قوی چند روز بیشتر طول بکشه .
و یه چیز دیگه که به نظر مهمتره یه نفز از روو سورس برنامه پسورد رو برمی داره ! میشه اینا کاریش کرد ؟!

پسوورد رو کاربر تایپ میکنه.
اون صد سال برای پسوورد های بالای 28 mixed-case alphanumeric هست.

برای اطمینان ۱۰۰٪ میتونید تعدادی کلید AES تصادفی رو با یک کلید نا متقارن ذخیره کنید و اون کلید نامتقارن رو با این روش رمزنگاری کنید.البته فقط وقتی موثر هست که کلید نا متقارن در محل اطلاعات نگهداری نشه و حتی در صورت نیاز airgap باشه. دقیقا مثل برنامه ای که در ابتدا نمونه کدش رو گذاشتم.

البته برنامه مذکور بازنویسی شده و در نسخه جدید خوانایی کد عملیات فوق بهتر شده. سعی میکنم تا یکی دو ماه آینده نسخه جدید رو آپلود کنم.

FastCode
یک شنبه 29 شهریور 1394, 07:24 صبح
این روش شکستن رمز مدت زیادی یکی از علاقه مندی های من بوده:
http://www.math.wisc.edu/~boston/nover.pdf
mirror:
https://eprint.iacr.org/2008/435.ps

البته هیچ وقت فرصت نکردم برای AES بنویسمش

negar.rafie
یک شنبه 29 شهریور 1394, 15:16 عصر
ممنون
من کد های شما در سی شارپ بردم و به این صورت استفاده کردم:

string iv;
byte[] passwordBytes = Encoding.UTF8.GetBytes(txtkey.Text);
textEncrypt.Text = EncryptText(txtPlaintext.Text, new byte[] { 0x89, 0x3A, 0x24, 0xA2, 0x3F, 0x4b, 0xfa, 0x18 }, passwordBytes, out iv);

خب حالا چندتا سوال مهم:
1- کدهای اول من که قرار دادم وقتی متن ورودی و کلید را بهش بدیم اگر هزار بار روی دکمه کلیک کنیم خروجی های مختلف میده که به نظرم به امنیت کمک میکنه ولی کد شما به ازای یک کلید و یک متن ورودی هزار بار هم روی دکمه کلید کنید یه خروجی بیشتر نمیده حالا برای این چکار کنیم و کجای کد را تغییر بدیم؟
2- در اینجا پارامتر سالت new byte[] { 0x89, 0x3A, 0x24, 0xA2, 0x3F, 0x4b, 0xfa, 0x18 } هستش ایا این باید همین طور ثابت بمونه و در کدمان همین را قرار دهیم؟
3- در کد من الگوریتم SHA256 برای هش کردن است ولی شما این حذف کردید ایا لازم نبوده که شما حذف کردید؟باشه بهتر نیست؟
4- شما iv را هم به خروجی ارسال کردید ایا بعدا به این نیاز میشه؟برای رمزگشایی؟

FastCode
دوشنبه 30 شهریور 1394, 07:15 صبح
۱.باید در جایی که iv رو مقداردهی کردم از کلاس Random در namespace ه System.Security استفاده کنید. ۲.خیر.این فقط یک نمونه هست. برای هر ورودی باید این مقدار تغییر کنه. به طور مثال میتونید از 'کد کاربری' کاربری که مالک اطلاعات هست به عنوان random seed یا ورودی تابع hash ه cryptographic استفاده کنید و خروچیش رو ایتجا استفاده کنید. ۳.PBKDF2 خودش این کار رو انجام میده. اکر میخواهید کار اضافه ای انجام بدید از یک hash ه memory-hard استفاده کنید. ۴.بله.بله.

negar.rafie
دوشنبه 30 شهریور 1394, 18:03 عصر
من تقریبا با مطالب تئوری اشنا هستم ولی یه کلاس قدرتمند برای الگوریتم aes میخوام باور کنید الان چند وقته دارم روش کار میکنم ولی خب هنوز به نتیجه نرسیدم

1- کلاس Random در namespace ه System.Security را پیدا نکردم؟
2- من فقط میخوام یک کلید وارد کنم ایا میشه همین پسورد را به عنوان سالت استفاده کرد؟
byte[] salet = Encoding.UTF8.GetBytes(txtkey.Text);
3- یعنی memory-hard بهتره ؟میشه به کد اضافه کنید؟
4- این iv را کجا ذخیره کنم داخل جدول دیتابیس؟چون کاربر که نباید هم این را حفظ کنه هم کلید را؟

FastCode
دوشنبه 30 شهریور 1394, 22:34 عصر
1.https://msdn.microsoft.com/en-us/library/system.security.cryptography.randomnumbergenerator .aspx
2.خیر.در حالت CBC و GCM که امنترین حالتها هستند این کار باعث میشه متن پسوورد وارد خروجی بشه.
فکر میکنم در IGE هم این اتفاق میافته.البته IGE معمولا امن نیست و نباید استفاده بشه.میگر اینکه دقیقا بدونید چکار دارید میکنید.
3.من نمونه memory-hard ندارم و فکر نمیکنم برای کار شما لازم باشه.به جای این کار تعداد rounds رو زیادتر کنید.
https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
4. یک آرایه رو هر بار با RandomNumberGenerator ایجاد کنید و در جدول ذخیره کنید.بایت های این آرایه رو با IV به دست آمده از PBKDF2 ترکیب کنید و به جای آن استفاده کنید. میتونید برای این کار از SHA استفاده کنید.

negar.rafie
سه شنبه 31 شهریور 1394, 09:59 صبح
1- منظورتون اینه:
byte[] passwordBytes = Encoding.UTF8.GetBytes(txtkey.Text);
var key = new RNGCryptoServiceProvider(passwordBytes);
key.GetBytes(passwordBytes);
AES.IV = key.GetBytes(passwordBytes);
2- پس از یک رشته دیگه استفاده میکنم مثلا نام کاربری
3- تعداد rounds رو کجا کد ببرم بالا؟
4- متوجه نشدم

FastCode
سه شنبه 31 شهریور 1394, 11:05 صبح
1.بله
2. اگر Salt توسط کاربر قابل تغییر باشه اتفاقات جالبی نمیافته.حواستون باشه.
3.new Rfc2898DeriveBytes (passpepper, userID, 65536 * rounds);
4.
byte[] myRandomBytes = rng.GetBytes(16);
byte[] IV = key.GetBytes(16)
for(int n=0;n!=16;n++)
IV[n] ^= myRandomBytes[n];
iv=myRandomBytes;
aes.IV=IV;

به حروف کوچک و بزرگ دقت کنید. حروف کوچک پارامتر تعریف شده در تابع هستند.

negar.rafie
سه شنبه 31 شهریور 1394, 11:20 صبح
1- ولی این کدی من نوشتم خطا میده نمیدونم چطور بنویسم:خجالت:
2- یعنی نباید از ورودی کاربر استفاده کنیم برای تولید salt؟پس چکار کنیم؟
3- اهان ولی خب الان rounds چه مقداریه که ضرب شده؟
4- الان این کدی که نوشتید جواب گزینه یک هم است؟چون iv مقداردهی شده؟بعد برای هر رشته رمزنگاری یک iv تولید میشه؟

اینطوری بخوایم پیش بریم فکر کنم باید تا یک ماه سوال جواب کنبم
جنابfastcode تا اینجا خیلی زحمت کشیدید و بیشتر کار را انجام دادید
حالا میشه کلاس کلاس کامل را به صورت یکجا قرار بدید رمزنگاری و رمزگشایی با Aes

و موارد زیر را شامل بشه:
1- کلاسی قدرتمند
2- جلوگیری از رمزگشایی با پسورد دیکشنری در الگوریتم های رمزنگاری
3- سرعت و امنیت بالا
4- و این موارد salt,iv هم طوری باشه که کاربر فقط یک کلید را نگهداری کنه

البته اگر وقت ندارید که هیچ و تا همینجا هم خیلی زحمت کشیدید و واقعا ازتون ممنونم و دیگ تاپیک را ادامه ندیم
ممنون

FastCode
سه شنبه 31 شهریور 1394, 17:30 عصر
این لینک رو هم حتما ببینید. در این مثال از GenerateKey و GenerateIV استفاده شده که پسورد قبول نمیکنه. این قسمت رو نمونش رو براتون گزاشتم.بقیه مطالبی که در لینک هست رو میتونید مستقیما استفاده کنید(مثل قسمت decrypt)
http://stackoverflow.com/questions/273452/using-aes-encryption-in-c-sharp


(کد کامپایل/تست نشده است.)

static byte[] AES_Encrypt (byte[] bytesToBeEncrypted, byte[] salt, byte[] passwordBytes, out byte[] iv)
{
MemoryStream ms = new MemoryStream ();
using (RijndaelManaged AES = new RijndaelManaged ()) {
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes (passwordBytes, salt, (65536 * 8) + 24 + 1);
AES.Key = key.GetBytes (AES.KeySize / 8);
System.Security.Cryptography.RandomNumberGenerator rng = new System.Security.Cryptography.RandomNumberGenerator ();
iv = rng.GetBytes(AES.BlockSize / 8);
byte[] IV = key.GetBytes (AES.BlockSize / 8);
for(int n = 0; n != IV.Length; n++) {
IV[n] ^= iv[n]
}
AES.IV = IV;
AES.Mode = CipherMode.CBC;
using (CryptoStream cs = new CryptoStream (ms, AES.CreateEncryptor (), CryptoStreamMode.Write)) {
cs.Write (bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close ();
cs.Clear ();
}
AES.Clear ();
Clear (bytesToBeEncrypted);
Clear (salt);
Clear (passwordBytes);
return ms.ToArray ();
}


2.سالت مقداری هست که ما خودمون تولید میکنیم و لو رفتنش هیچ اشکال امنیتی ای ایجاد نمیکنه.تنها نکته مهمش اینه که نباید کسی توی تایینش دست داشته باشه.یعنی باید random باشه یا از یک جای مشخص بیاد که کاربر توش دست نداره.
3.هر مقداری.توی نمونه کد ۸ داده بودم.
4.بله.

negar.rafie
سه شنبه 31 شهریور 1394, 19:11 عصر
ممنون
از خطهای زیر خطا میگیره:

System.Security.Cryptography.RandomNumberGenerator rng = new System.Security.Cryptography.RandomNumberGenerator ();
iv = rng.GetBytes(AES.BlockSize / 8);

همین کدهایی که منم نوشتم خطا میداد و گفتم نمیتونم بنویسم

FastCode
چهارشنبه 01 مهر 1394, 10:40 صبح
ببخشید. این کلاس constructor نداره.
از Create() استفاده کنید.

negar.rafie
چهارشنبه 01 مهر 1394, 11:21 صبح
اینطوری:
ولی از خط دوم ارور میگیره:

RandomNumberGenerator rng = RandomNumberGenerator.Create();
iv = rng.GetBytes(AES.BlockSize / 8);

FastCode
چهارشنبه 01 مهر 1394, 13:11 عصر
متن خطا لطفا؟

negar.rafie
چهارشنبه 01 مهر 1394, 16:18 عصر
این خطا را میده جناب فست کد:

135449

می نمیتونه int را به بایت تبدیل کنه

FastCode
چهارشنبه 01 مهر 1394, 21:14 عصر
یه آرایه با طولی که حساب کردیم ایجاد کنید و به عنوان آرگومان بهش بدید

byte[] IV = new byte[AES.BlockSize / 8];
key.GetBytes (IV);

negar.rafie
پنج شنبه 02 مهر 1394, 11:11 صبح
نشد
فکر کنم بیخیال بشم بهتره
اخه قسمت رمزنگاری یه پروژه مهم به عهده من است
اگر اینطوری بخوام با وارد کردن متغییرها و و موارد دیگه انجام بدم امکان داره پروژه به مشکل بربخوره
من 2 ساله دارم روی رمزنگاری تحقیق میکنم از زمانی که تاپیک زیر را زدم

http://barnamenevis.org/showthread.php?357912-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D8%B1%D9%85%D8%B2%D9%86%DA%AF%D8%A7%D8%B1%DB%8C-Encrypt-Decrypt

با مطالب تئوری رمزنگاری تقریبا اشنایی دارم ولی دنبال یه کلاس کامل برای aes هستم
کدی که من گذاشتم کار میکنه و من خیلی تستش کردم
ولی خب شما گفتید که سالت نباید به متن اضافه بشه
حالا نمیدونم چکار کنم

abdullah20
شنبه 04 مهر 1394, 08:17 صبح
خانم رفیعی با اون سورسی که براتون فرستادم مگه کارتون راه نیافتد؟
البته اون مربوط به رمزنگاری فایل های حجیم بود ولی با چندتا تغییر ساده میتونید برای رمزنگاری متن هم استفاده کنید