PDA

View Full Version : هش کردن و دی هش کردن در جاوا



cnmeysam
یک شنبه 21 آبان 1396, 14:48 عصر
سلام من یه فرم ساختم برای ثبت یوزرها توی دیتابیس و برای اینکه پسورد ها امنیت داشته باشن پسوردها رو هش کردم با کمک این کد



//هش پسورد
String password = txtpass1.getText();

try
{
lblhash.setText(HashPaasword(password));
}
catch(NoSuchAlgorithmException e){Logger.getLogger(this.getName()).log(Level.SEVE RE, null, e);}
//هش پسورد



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



//هش پسورد
String password = new String(txtpass.getPassword());

try
{
lblhash.setText(HashPaasword(password));
}
catch(NoSuchAlgorithmException e){Logger.getLogger(this.getName()).log(Level.SEVE RE, null, e);}
//هش پسورد

//ورود
try
{

FileReader reader = new FileReader("C:\\Windows\\System32\\ok.dll");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
String url =line;

Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();

String _uname = txtuser.getText();
String _pass = lblhash.getText();
int rowcount = -1;
ResultSet result = stmt.executeQuery( "SELECT COUNT(*) FROM tbl_account WHERE uname='"+_uname+"' "
+ "AND password='"+_pass+"'");
result.next();
rowcount = result.getInt(1);
stmt.close();
con.close();
if(rowcount>0)
{
lbltest.setText("خوش آمدید");
defaultpack.main main = new defaultpack.main(per);

main.setVisible(true);
this.dispose();
}
else
{
lbltest.setText("مشخصات وارد شده صحیح نمی باشد");
}


}
}
catch (Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
Logger.getLogger(this.getName()).log(Level.SEVERE, null, ex);
}
//ورود



البته کانکشن رو توی یه فایل dll ذخیره کردم از اون فراخوانی میکنه
میخواستم ببینم چطوری میتونم اون کد هشی که توی دیتابیس دارم دوباره دی هش کنم که مجبور نباشم از اون لیبل استفاده کنم؟

vahid-p
یک شنبه 21 آبان 1396, 15:37 عصر
البته یه کلک رشتی زدم یعنی دوباره گفتم پسوردی که توی پسورد کاربر مینویسه دوباره هش کن بریز توی یه لیبل و اون لیبل رو با پسورد ذخیره شده توی دیتابیس مقایسه کن
این کلک نیست، دقیقا کاریه که همه سایت ها انجام میدن و درستش همینه (البته یه سری کارهای دیگه هم میکنن برای امنیت بیشتر). چون خیلی از Hashها یک طرفه یا به گفته ای غیرمتقارن هستن. مثل SHA256 و خوبیش هم به همینه که شما از روی مقدار Hash شده نمیتونید مقدار اولیه رو پیدا کنید (تقریبا غیرممکنه). ولی سایتهایی هم دیدم که هش های MD5 رو بهشون میدی و عکسش رو محاسبه میکنند که دیتابیس عظیمی از مقادیر ممکن و هش هاش رو دارن که البته خیلی بزرگ میشه چنین دیتابیسی! مثل http://md5decrypt.net

cnmeysam
یک شنبه 21 آبان 1396, 19:16 عصر
ممنون از توضیحتون ولی یه سوال برام پیش میاد اگه بخوام یک مقداری رو هش کنم توی برنامم مثلا همون کانکشن استرینگ که توی dll ذخیره کردم که اگه کاربر بهش دسترسی داشت نتونه مشخصات و یوزر پس سرور رو ببینه بعد دوباره از هش در بیارم باید چیکار کنم؟

cnmeysam
دوشنبه 22 آبان 1396, 01:22 صبح
من خیلی گشتم یه راه پیدا کردم ولی نمیدونم راه درستی هست یا نه میشه نظرتون رو بگید؟البته میدونم امنیتش کمه ولی باز هم اگه راه بهتری بلدید بهم بگید ممنون میشم
برای انکریپت کردن


String strip = jTextField1.getText();
byte[] encryptArray = Base64.encodeBase64(strip.getBytes());
String encstr;
try {
encstr = new String(encryptArray,"UTF-8");
jTextField2.setText(encstr);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(ascci.class.getName()).log(Level. SEVERE, null, ex);
}



وبرای دی کریپت کردن از این کد استفاده کردم



String strDec = jTextField2.getText();
byte[] dectryptArray = strDec.getBytes();
byte[] decarray = Base64.decodeBase64(dectryptArray);
String ok;
try {
ok = new String(decarray,"UTF-8");
jTextField3.setText(ok);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(ascci.class.getName()).log(Level. SEVERE, null, ex);
}



این رو هم اینپورت کردم


import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.codec.binary.Base64;



و این کتابخونه رو هم به لایبرری اضافه کردم تو ضمیمه گذاشتم
org-apache-commons-codec.jar

vahid-p
دوشنبه 22 آبان 1396, 11:10 صبح
نه روش خوبی که نیست. اصولا نمیتونی چنین چیزی به کاربر بدی و روی سیستم کاربر decrypt بشه توسط کد شما ولی کاربر نتونه decrypt اش کنه. فقط در نگاه اول آره نمیتونه پسورد رو بفهمه.
اگر همینقدر براتون کفایت میکنه که هیچی. ولی اصولا پسورد اگر قراره نفهمه به این سادگی هم نباید بتونه decrypt کنه.

اگر دیتابیس رو سیستم کاربر هست که چه دلیلی داره کاربر نفهمه رمز عبور چیه؟
اگر دیتابیس رو سرورتون هست که کاربر اصلا بهش دسترسی نداره. و معمولا پسوردها روی سرور به صورت تکست معمولی ذخیره میشه چون کسی که بتونه سرور رو هک کنه، decrypt کردن چنین رمزنگاری های دو طرفه ای هم براش کاری نداره

cnmeysam
دوشنبه 22 آبان 1396, 12:45 عصر
سلام منظور من رو درست متوجه نشدید
من نمیخوام یوزر پسوردهای اکانت ها رو کاربر نبینه برای اون از همون روش که اول گفتم استفاده کردم
یعنی پسورد هش شده بعد هش شده با یه لیبل مقایسه میشه نه تکستی که کاربر پسوردشو توش مینویسه
من میخوام کانکشن استرینگم رو که توی dll هست انکریپت کنم
چون نیاز هستش توی پوشه ای که برنامه توش نصب میشه بذارمش
نمیخوام توی سیستم 32 باشه یا حتی توی رجیستری ثبتش کنم تا برنامه بتونه هم توی لینوکس اجرا بشه هم توی مک هم توی ویندوز توی لیوکس و مک که آدرسی مثل c:\windows\system32 وجود نداره رجیستری هم ندارن تنها راهی که به ذهنم رسید ساختن یه فایل dll کنار برنامه که مشخصات اتصال به دیتابیس رو توش بریزم و ازش فراخوانی کنم
دلیل اینکه باید کانکشنم داینامیک باشه هم اینه (یه فرم دارم که ادمین خودش مشخصات سرور رو توش میزنه ) برنامه قراره چند جا نصب بشه و هر کسی مشخصات و تنظیمات سرورش مثل port و یوزر پس و ... رو متفاوت میذارن و ITman باید این امکان رو داشته باشه که برنامه رو با تنظیمات سرور خودش هماهنگ کنه
در هر صورت سناریو اینه که توضیح دادم اگه راه بهتری وجود داره برای داینامیک بودن کانکشن استرینگم خوشحال میشم راهنماییم کنید و یه نمونه برام بذارید